Merged revisions 116463 via svnmerge from
authorRussell Bryant <russell@russellbryant.com>
Wed, 14 May 2008 21:40:43 +0000 (21:40 +0000)
committerRussell Bryant <russell@russellbryant.com>
Wed, 14 May 2008 21:40:43 +0000 (21:40 +0000)
https://origsvn.digium.com/svn/asterisk/branches/1.4

........
r116463 | russell | 2008-05-14 16:32:00 -0500 (Wed, 14 May 2008) | 4 lines

Add ast_assert(), which can be used to handle fatal errors.  It is only compiled
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/trunk@116469 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 20e1fc4..decf022 100644 (file)
@@ -1008,7 +1008,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 9fdc6de..5177734 100644 (file)
@@ -1597,18 +1597,10 @@ static inline enum ast_t38_state ast_channel_get_t38_state(struct ast_channel *c
        return state;
 }
 
-
-#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 be7d3fb..0de0727 100644 (file)
@@ -654,6 +654,33 @@ int ast_mkdir(const char *path, int mode);
 
 #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
+
 #include "asterisk/strings.h"
 
 #endif /* _ASTERISK_UTILS_H */
index df822f5..e51187d 100644 (file)
@@ -430,7 +430,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;
                }
                
@@ -486,7 +486,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 0999244..745d0cf 100644 (file)
@@ -982,7 +982,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 {
                        ast_debug(1, "Dropping voice to exceptionally long queue on %s\n", chan->name);
                        ast_frfree(f);
@@ -1625,7 +1625,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)) {
                ast_debug(1, "Hanging up channel '%s'\n", chan->name);
index e7f8496..647ed80 100644 (file)
@@ -1096,8 +1096,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;
@@ -1440,8 +1439,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 64ef413..91d8616 100644 (file)
@@ -373,9 +373,7 @@ int ast_sched_del(struct sched_context *con, int id)
 
        if (!s) {
                ast_debug(1, "Attempted to delete nonexistent schedule entry %d!\n", id);
-#ifdef DO_CRASH
-               CRASH;
-#endif
+               ast_assert(0);
                return -1;
        }
        
index 7dea4d8..ea78f09 100644 (file)
@@ -659,8 +659,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;
        }