Index: include/asterisk/channel.h =================================================================== --- include/asterisk/channel.h (revision 79777) +++ include/asterisk/channel.h (working copy) @@ -478,6 +478,8 @@ /*! This is set to tell the channel not to generate DTMF begin frames, and * to instead only generate END frames. */ AST_FLAG_END_DTMF_ONLY = (1 << 14), + /*! XXX For debugging, not to be committed */ + AST_FLAG_CHANNEL_FREE = (1 << 15), }; /*! \brief ast_bridge_config flags */ Index: main/channel.c =================================================================== --- main/channel.c (revision 79777) +++ main/channel.c (working copy) @@ -899,6 +899,11 @@ int blah = 1; int qlen = 0; + if (ast_test_flag(chan, AST_FLAG_CHANNEL_FREE)) { + ast_log(LOG_ERROR, "This channel is already being free'd. This would crash!\n"); + return -1; + } + /* Build us a copy and free the original one */ if (!(f = ast_frdup(fin))) { ast_log(LOG_WARNING, "Unable to duplicate frame\n"); @@ -906,6 +911,13 @@ } ast_channel_lock(chan); + if (ast_test_flag(chan, AST_FLAG_CHANNEL_FREE)) { + ast_log(LOG_ERROR, "This channel is already being free'd. This would crash!\n"); + ast_frfree(f); + ast_channel_unlock(chan); + return -1; + } + /* See if the last frame on the queue is a hangup, if so don't queue anything */ if ((cur = AST_LIST_LAST(&chan->readq)) && (cur->frametype == AST_FRAME_CONTROL) && (cur->subclass == AST_CONTROL_HANGUP)) { ast_frfree(f); @@ -913,6 +925,12 @@ return 0; } + if (ast_test_flag(chan, AST_FLAG_CHANNEL_FREE)) { + ast_log(LOG_ERROR, "This channel is already being free'd. This would crash!\n"); + ast_frfree(f); + ast_channel_unlock(chan); + return -1; + } /* Count how many frames exist on the queue */ AST_LIST_TRAVERSE(&chan->readq, cur, frame_list) { qlen++; @@ -931,7 +949,21 @@ return 0; } } + + if (ast_test_flag(chan, AST_FLAG_CHANNEL_FREE)) { + ast_log(LOG_ERROR, "This channel is already being free'd. This would crash!\n"); + ast_frfree(f); + ast_channel_unlock(chan); + return -1; + } AST_LIST_INSERT_TAIL(&chan->readq, f, frame_list); + + if (ast_test_flag(chan, AST_FLAG_CHANNEL_FREE)) { + ast_log(LOG_ERROR, "This channel is already being free'd. This would crash!\n"); + ast_frfree(f); + ast_channel_unlock(chan); + return -1; + } if (chan->alertpipe[1] > -1) { if (write(chan->alertpipe[1], &blah, sizeof(blah)) != sizeof(blah)) ast_log(LOG_WARNING, "Unable to write to alert pipe on %s, frametype/subclass %d/%d (qlen = %d): %s!\n", @@ -1195,7 +1227,9 @@ struct varshead *headp; struct ast_datastore *datastore = NULL; char name[AST_CHANNEL_NAME]; - + + ast_set_flag(chan, AST_FLAG_CHANNEL_FREE); + headp=&chan->varshead; AST_LIST_LOCK(&channels);