Summary: | ASTERISK-07656: [patch] Fix race condion crash with get_member_status | ||
Reporter: | Tim Ringenbach at Asteria Solutions Group (tim_ringenbach) | Labels: | |
Date Opened: | 2006-09-01 10:31:26 | Date Closed: | 2006-09-28 10:36:45 |
Priority: | Critical | Regression? | No |
Status: | Closed/Complete | Components: | Applications/app_queue |
Versions: | Frequency of Occurrence | ||
Related Issues: | |||
Environment: | Attachments: | ( 0) queue_member_race.diff ( 1) queue.diff | |
Description: | The patch is against latest branch 1.2. The crash happened on 1.2.9.1 #0 wait_our_turn (qe=0xb68f5b60, ringing=0, reason=0xb68f5b54) at app_queue.c:443 443 if (member->paused) continue; (gdb) l 438 { 439 struct member *member; 440 enum queue_member_status result = QUEUE_NO_MEMBERS; 441 442 for (member = q->members; member; member = member->next) { 443 if (member->paused) continue; 444 445 switch (member->status) { 446 case AST_DEVICE_INVALID: 447 /* nothing to do */ (gdb) p member No symbol "member" in current context. (gdb) info locals res = 0 (gdb) l- Undefined command: "l-". Try "help". (gdb) l - 428 new->opos = *pos; 429 } 430 431 enum queue_member_status { 432 QUEUE_NO_MEMBERS, 433 QUEUE_NO_REACHABLE_MEMBERS, 434 QUEUE_NORMAL 435 }; 436 437 static enum queue_member_status get_member_status(const struct ast_call_queue *q) (gdb) bt #0 wait_our_turn (qe=0xb68f5b60, ringing=0, reason=0xb68f5b54) at app_queue.c:443 #1 0xb740556c in queue_exec (chan=0x83a1860, data=0xb68f5b60) at app_queue.c:3094 #2 0x0808ec72 in pbx_extension_helper (c=0x83a1860, con=0x5f747361, context=0x83a19b0 "call_agi", exten=0x83a1aa4 "queue", priority=2, label=0x0, callerid=0x0, action=0) at pbx.c:553 #3 0x0808f89f in __ast_pbx_run (c=0x83a1860) at pbx.c:2230 #4 0x0809058f in pbx_thread (data=0x5f747361) at pbx.c:2517 ASTERISK-1 0xb7efeb50 in start_thread () from /lib/libpthread.so.0 ASTERISK-2 0xb7de789e in clone () from /lib/libc.so.6 (gdb) frame 0 #0 wait_our_turn (qe=0xb68f5b60, ringing=0, reason=0xb68f5b54) at app_queue.c:443 443 if (member->paused) continue; (gdb) info locals res = 0 (gdb) l 443 438 { 439 struct member *member; 440 enum queue_member_status result = QUEUE_NO_MEMBERS; 441 442 for (member = q->members; member; member = member->next) { 443 if (member->paused) continue; 444 445 switch (member->status) { 446 case AST_DEVICE_INVALID: 447 /* nothing to do */ (gdb) l 442 437 static enum queue_member_status get_member_status(const struct ast_call_queue *q) 438 { 439 struct member *member; 440 enum queue_member_status result = QUEUE_NO_MEMBERS; 441 442 for (member = q->members; member; member = member->next) { 443 if (member->paused) continue; 444 445 switch (member->status) { 446 case AST_DEVICE_INVALID: (gdb) bt #0 wait_our_turn (qe=0xb68f5b60, ringing=0, reason=0xb68f5b54) at app_queue.c:443 #1 0xb740556c in queue_exec (chan=0x83a1860, data=0xb68f5b60) at app_queue.c:3094 #2 0x0808ec72 in pbx_extension_helper (c=0x83a1860, con=0x5f747361, context=0x83a19b0 "call_agi", exten=0x83a1aa4 "queue", priority=2, label=0x0, callerid=0x0, action=0) at pbx.c:553 #3 0x0808f89f in __ast_pbx_run (c=0x83a1860) at pbx.c:2230 #4 0x0809058f in pbx_thread (data=0x5f747361) at pbx.c:2517 ASTERISK-1 0xb7efeb50 in start_thread () from /lib/libpthread.so.0 ASTERISK-2 0xb7de789e in clone () from /lib/libc.so.6 (gdb) p *qe $1 = {parent = 0x823a060, moh = '\0' <repeats 79 times>, announce = '\0' <repeats 79 times>, context = '\0' <repeats 79 times>, digits = '\0' <repeats 79 times>, pos = 19, prio = 0, last_pos_said = 19, last_periodic_announce_time = 1157118781, last_pos = 1157119534, opos = 23, handled = 0, start = 1157118781, expire = 0, chan = 0x83a1860, next = 0xb6bcfb60} (gdb) p stat No symbol "stat" in current context. (gdb) p qe->parent $2 = (struct ast_call_queue *) 0x823a060 (gdb) p *qe->parent $3 = {lock = {__data = {__lock = 0, __count = 0, __owner = 0, __kind = 1, __nusers = 0, __spins = 0}, __size = '\0' <repeats 12 times>, "\001\000\000\000\000\000\000\000\000\000\000", __align = 0}, name = "Support_Queue", '\0' <repeats 66 times>, moh = '\0' <repeats 79 times>, announce = '\0' <repeats 79 times>, context = '\0' <repeats 79 times>, monjoin = 0, dead = 0, joinempty = 0, eventwhencalled = 1, leavewhenempty = 0, reportholdtime = 0, wrapped = 0, timeoutrestart = 0, announceholdtime = 1, strategy = 0, maskmemberstatus = 0, realtime = 0, announcefrequency = 30, periodicannouncefrequency = 0, roundingseconds = 0, holdtime = 0, callscompleted = 0, callsabandoned = 0, servicelevel = 0, callscompletedinsl = 0, monfmt = "\000\000\000\000\000\000\000", sound_next = "queue-youarenext", '\0' <repeats 63 times>, sound_thereare = "queue-thereare", '\0' <repeats 65 times>, sound_calls = "queue-callswaiting", '\0' <repeats 61 times>, sound_holdtime = "queue-holdtime", '\0' <repeats 65 times>, sound_minutes = "queue-minutes", '\0' <repeats 66 times>, sound_lessthan = "queue-less-than", '\0' <repeats 64 times>, sound_seconds = "queue-seconds", '\0' <repeats 66 times>, sound_thanks = "queue-thankyou", '\0' <repeats 65 times>, sound_reporthold = "queue-reporthold", '\0' <repeats 63 times>, sound_periodicannounce = "queue-periodic-announce", '\0' <repeats 56 times>, ringinuse = 0, count = 24, maxlen = 30, wrapuptime = 0, retry = 5, timeout = 0, weight = 0, rrpos = 0, memberdelay = 0, members = 0x831e510, head = 0xb654bb60, next = 0x0} (gdb) p *qe->parent->members $4 = {interface = "SIP/7108", '\0' <repeats 71 times>, penalty = 1, calls = 0, dynamic = 0, status = 5, paused = 0, lastcall = 0, in_call = 0, dead = 0, delme = 0, next = 0x835d9a0} (gdb) p *qe->parent->members->next $5 = {interface = "ho2\b?H??\000\000\000\000\000\000\000\000\001\000\000\000@\000\000\000\020?5\b\020?5\b", '\0' <repeats 47 times>, penalty = 1, calls = 0, dynamic = 0, status = 4, paused = 0, lastcall = 0, in_call = 0, dead = 0, delme = 1, next = 0x5f747361} (gdb) | ||
Comments: | By: Anthony LaMantia (alamantia) 2006-09-25 11:02:07 i applied this patch to the latest 1.2 subversion branch in this testing tree.. http://svn.digium.com/view/asterisk/team/anthonyl/7864-patch/ it looks like we may want to add the locking of the call queue in other versions of asterisk as well as get_member_status() still preforms no locking in the 1.4 betas or trunk. By: Anthony LaMantia (alamantia) 2006-09-25 11:10:35 uploaded a diff aginst the trunk version of asterisk for this bug. By: Anthony LaMantia (alamantia) 2006-09-26 11:44:25 tim_ringenbach: ping By: Tim Ringenbach at Asteria Solutions Group (tim_ringenbach) 2006-09-26 13:33:06 pong. What exactly did you need? By: Anthony LaMantia (alamantia) 2006-09-27 16:46:25 nothing( i think i got a few bugid's confused) this looks good, i'd like to get another person to check this out before it's commited. but it's working fine for me By: BJ Weschke (bweschke) 2006-09-28 10:36:44 committed to 1.2, 1.4, and /trunk. Thanks! |