[Home]

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:26Date Closed:2006-09-28 10:36:45
Priority:CriticalRegression?No
Status:Closed/CompleteComponents: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!