]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Add ast_assert(), which can be used to handle fatal errors. It is only compiled
authorRussell Bryant <russell@russellbryant.com>
Wed, 14 May 2008 21:32:00 +0000 (21:32 +0000)
committerRussell Bryant <russell@russellbryant.com>
Wed, 14 May 2008 21:32:00 +0000 (21:32 +0000)
in if dev-mode is enabled, and only aborts if DO_CRASH is defined.
(inspired by issue #12650)

git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.4@116463 65c4cc65-6c06-0410-ace0-fbb531ad65f3

channels/chan_agent.c
include/asterisk/channel.h
include/asterisk/utils.h
main/abstract_jb.c
main/channel.c
main/rtp.c
main/sched.c
main/udptl.c

index ae6d093c79b31895a76dd8f89ff5f7fe1bb8bd02..4149f1c7fc7d458f8c865951e618d770f851754b 100644 (file)
@@ -1051,7 +1051,7 @@ static struct ast_channel *agent_new(struct agent_pvt *p, int state)
        if (p->chan) {
                if (ast_test_flag(p->chan, AST_FLAG_BLOCKING)) {
                        ast_log( LOG_ERROR, "A blocker exists after agent channel ownership acquired\n" );
-                       CRASH;
+                       ast_assert(0);
                }
        }
        return tmp;
index 1172274f78fb2b646fc71807d527885afe1d3053..41371ccc044ca70d0ea9d5110b69f7bbaa5b5628 100644 (file)
@@ -1340,17 +1340,10 @@ static inline int ast_select(int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds,
 #endif
 }
 
-#ifdef DO_CRASH
-#define CRASH do { fprintf(stderr, "!! Forcing immediate crash a-la abort !!\n"); *((int *)0) = 0; } while(0)
-#else
-#define CRASH do { } while(0)
-#endif
-
 #define CHECK_BLOCKING(c) do {          \
        if (ast_test_flag(c, AST_FLAG_BLOCKING)) {\
                if (option_debug) \
                        ast_log(LOG_DEBUG, "Thread %ld Blocking '%s', already blocked by thread %ld in procedure %s\n", (long) pthread_self(), (c)->name, (long) (c)->blocker, (c)->blockproc); \
-               CRASH; \
        } else { \
                (c)->blocker = pthread_self(); \
                (c)->blockproc = __PRETTY_FUNCTION__; \
index 1e5203671eaeaff39e8be5f9311912d0d6dc1b6e..44994f4c078f290f8d4f38f17f272cbd90485116 100644 (file)
@@ -562,4 +562,31 @@ void ast_enable_packet_fragmentation(int sock);
 
 #define ARRAY_LEN(a) (sizeof(a) / sizeof(a[0]))
 
+#ifdef AST_DEVMODE
+#define ast_assert(a) _ast_assert(a, # a, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+static void force_inline _ast_assert(int condition, const char *condition_str, 
+       const char *file, int line, const char *function)
+{
+       if (__builtin_expect(!condition, 1)) {
+               /* Attempt to put it into the logger, but hope that at least someone saw the
+                * message on stderr ... */
+               ast_log(LOG_ERROR, "FRACK!, Failed assertion %s (%d) at line %d in %s of %s\n",
+                       condition_str, condition, line, function, file);
+               fprintf(stderr, "FRACK!, Failed assertion %s (%d) at line %d in %s of %s\n",
+                       condition_str, condition, line, function, file);
+               /* Give the logger a chance to get the message out, just in case we abort(), or
+                * Asterisk crashes due to whatever problem just happened after we exit ast_assert(). */
+               usleep(1);
+#ifdef DO_CRASH
+               abort();
+               /* Just in case abort() doesn't work or something else super silly,
+                * and for Qwell's amusement. */
+               *((int*)0)=0;
+#endif
+       }
+}
+#else
+#define ast_assert(a)
+#endif
+
 #endif /* _ASTERISK_UTILS_H */
index ed260007009b7b5de729e3de6248cd2edb2d7e9b..25bd8fd0d7d2ab7c86fb30c39e841c4c9188cbb2 100644 (file)
@@ -433,7 +433,7 @@ static void jb_get_and_deliver(struct ast_channel *chan)
                        return;
                default:
                        ast_log(LOG_ERROR, "This should never happen!\n");
-                       CRASH;
+                       ast_assert(0);
                        break;
                }
                
@@ -489,7 +489,7 @@ static int create_jb(struct ast_channel *chan, struct ast_frame *frr)
                bridged = ast_bridged_channel(chan);
                if (!bridged) {
                        /* We should always have bridged chan if a jitterbuffer is in use */
-                       CRASH;
+                       ast_assert(0);
                }
                snprintf(name1, sizeof(name1), "%s", bridged->name);
                tmp = strchr(name1, '/');
index d9ab77c382177684cb29f376385db5543d2065d0..392b0b113ef711e6a588e15c58e658e9924cd5ec 100644 (file)
@@ -912,7 +912,7 @@ int ast_queue_frame(struct ast_channel *chan, struct ast_frame *fin)
        if (((fin->frametype == AST_FRAME_VOICE) && (qlen > 96)) || (qlen  > 128)) {
                if (fin->frametype != AST_FRAME_VOICE) {
                        ast_log(LOG_WARNING, "Exceptionally long queue length queuing to %s\n", chan->name);
-                       CRASH;
+                       ast_assert(0);
                } else {
                        if (option_debug)
                                ast_log(LOG_DEBUG, "Dropping voice to exceptionally long queue on %s\n", chan->name);
@@ -1476,7 +1476,7 @@ int ast_hangup(struct ast_channel *chan)
                ast_log(LOG_WARNING, "Hard hangup called by thread %ld on %s, while fd "
                                        "is blocked by thread %ld in procedure %s!  Expect a failure\n",
                                        (long)pthread_self(), chan->name, (long)chan->blocker, chan->blockproc);
-               CRASH;
+               ast_assert(0);
        }
        if (!ast_test_flag(chan, AST_FLAG_ZOMBIE)) {
                if (option_debug)
index 658bd08910a47003dbb6fe1e9b41fd630ccdb5d6..2597fb17857466ad760f5558b8f07cef979f0362 100644 (file)
@@ -855,8 +855,7 @@ struct ast_frame *ast_rtcp_read(struct ast_rtp *rtp)
        rtcpheader = (unsigned int *)(rtcpdata + AST_FRIENDLY_OFFSET);
        
        if (res < 0) {
-               if (errno == EBADF)
-                       CRASH;
+               ast_assert(errno != EBADF);
                if (errno != EAGAIN) {
                        ast_log(LOG_WARNING, "RTCP Read error: %s.  Hanging up.\n", strerror(errno));
                        return NULL;
@@ -1134,8 +1133,7 @@ struct ast_frame *ast_rtp_read(struct ast_rtp *rtp)
 
        rtpheader = (unsigned int *)(rtp->rawdata + AST_FRIENDLY_OFFSET);
        if (res < 0) {
-               if (errno == EBADF)
-                       CRASH;
+               ast_assert(errno != EBADF);
                if (errno != EAGAIN) {
                        ast_log(LOG_WARNING, "RTP Read error: %s.  Hanging up.\n", strerror(errno));
                        return NULL;
index 04589a0186c189575c2962d6a5602be428d2bca8..935e85398af93e3e27425d89bc70b1a36632d6d3 100644 (file)
@@ -282,9 +282,7 @@ int ast_sched_del(struct sched_context *con, int id)
        if (!s) {
                if (option_debug)
                        ast_log(LOG_DEBUG, "Attempted to delete nonexistent schedule entry %d!\n", id);
-#ifdef DO_CRASH
-               CRASH;
-#endif
+               ast_assert(0);
                return -1;
        }
        
index 718b46fb84e137c5a610e2844e4f6ff90d53499c..a9386ac099bb734c38f4f74be761ea4ad244ac80 100644 (file)
@@ -639,8 +639,7 @@ struct ast_frame *ast_udptl_read(struct ast_udptl *udptl)
        if (res < 0) {
                if (errno != EAGAIN)
                        ast_log(LOG_WARNING, "UDPTL read error: %s\n", strerror(errno));
-               if (errno == EBADF)
-                       CRASH;
+               ast_assert(errno != EBADF);
                return &ast_null_frame;
        }