[asterisk-bugs] [Asterisk 0006176]: [patch] Segfault in pbx_builtin_setvar_helper. Looks like the channel is being closed down underneath us
Asterisk Bug Tracker
noreply at bugs.digium.com
Wed Feb 11 14:55:50 CST 2009
A NOTE has been added to this issue.
======================================================================
http://bugs.digium.com/view.php?id=6176
======================================================================
Reported By: stevedavies
Assigned To: Corydon76
======================================================================
Project: Asterisk
Issue ID: 6176
Category: Applications/app_macro
Reproducibility: random
Severity: crash
Priority: normal
Status: closed
Asterisk Version: SVN
Regression: No
SVN Branch (only for SVN checkouts, not tarball releases): trunk
SVN Revision (number only!): 9156
Request Review:
Resolution: fixed
Fixed in Version:
======================================================================
Date Submitted: 2006-01-09 04:09 CST
Last Modified: 2009-02-11 14:55 CST
======================================================================
Summary: [patch] Segfault in pbx_builtin_setvar_helper.
Looks like the channel is being closed down underneath us
Description:
Site had a segfault. gdb backtraces attached.
I had a look at what happened...
Segfault was in pbx_builtin_setvar_helper, whilst executing in the
AST_LIST_REMOVE macro.
pbx_builtin_setvar_helper was called by macro_exec, which was trying to
set MACRO_DEPTH on the channel.
Guilty code at pbx.c around line 5751 (SVN trunk, r7839):
AST_LIST_TRAVERSE (headp, newvariable, entries) {
if (strcasecmp(ast_var_name(newvariable), nametail) == 0)
{
/* there is already such a variable, delete it */
AST_LIST_REMOVE(headp, newvariable, entries);
ast_var_delete(newvariable);
break;
}
}
headp here points at varshead in the channel structure.
Apparently at the time the list was traversed, there must have been
variables on the channel - given that an existing MACRO_DEPTH was found to
delete.
However, by the time we got into the AST_LIST_REMOVE code, curelm was null
(which comes from (head)->first, i.e. varshead.first).
(gdb) frame 0
http://bugs.digium.com/view.php?id=0 0x080900a2 in pbx_builtin_setvar_helper
(chan=0x88d8a30, name=0x72734e
"MACRO_DEPTH", value=0xb79ee2b0 "1") at pbx.c:5941
5941 AST_LIST_REMOVE(headp, newvariable,
entries);
(gdb) p curelm
$2 = (struct ast_var_t *) 0x0
Here's AST_LIST_REMOVE:
#define AST_LIST_REMOVE(head, elm, field) do { \
if ((head)->first == (elm)) { \
(head)->first = (elm)->field.next; \
} \
else { \
typeof(elm) curelm = (head)->first; \
while (curelm->field.next != (elm)) \
curelm = curelm->field.next; \
curelm->field.next = (elm)->field.next; \
} \
if ((head)->last == elm) \
(head)->last = NULL; \
} while (0)
So my theory is that the channel was busy being dismantled as we tried to
remove the variable.
Here's the channel at the time of the segfault:
(gdb) frame 1
http://bugs.digium.com/view.php?id=1 0x00726701 in macro_exec (chan=0x88d8a30,
data=0xb79f27e0) at
app_macro.c:253
253 pbx_builtin_setvar_helper(chan, "MACRO_DEPTH", depthc);
(gdb) p *chan
$3 = {name = "Parking/Local/91001 at from-internal-74b8,2<ZOMBIE>", '\0'
<repeats 31 times>, tech = 0x80f4600, tech_pvt = 0x0,
language = "en", '\0' <repeats 17 times>, type = 0x7ee627 "Local", fds =
{-1, -1, -1, -1, -1, -1, 172, -1},
musicclass = '\0' <repeats 19 times>, music_state = 0xb6602dd8,
generatordata = 0x0, generator = 0x0, _bridge = 0x0, masq = 0x0,
masqr = 0x0, cdrflags = 0, _softhangup = 1, whentohangup = 0, blocker =
3080698800, lock = {__m_reserved = 0, __m_count = 0,
__m_owner = 0x0, __m_kind = 1, __m_lock = {__status = 0, __spinlock =
0}}, blockproc = 0x80f4a24 "ast_waitfor_nandfds",
appl = 0xb7b437b0 "Macro", data = 0xb79f27e0 "dial|30|tTrh|91001", fdno
= 6, sched = 0x8a3f2c8, streamid = -1, stream = 0x0,
vstreamid = 0, vstream = 0x0, oldwriteformat = 64, timingfd = 172,
timingfunc = 0, timingdata = 0x0, _state = 0, rings = 0,
nativeformats = 8, readformat = 8, writeformat = 8, cid = {cid_dnid =
0x0, cid_num = 0x0, cid_name = 0x0, cid_ani = 0x0,
cid_rdnis = 0x0, cid_pres = 0, cid_ani2 = 0, cid_ton = 0, cid_tns =
0},
context = "macro-dial\000-vm\000able", '\0' <repeats 60 times>,
macrocontext = "from-internal", '\0' <repeats 66 times>,
macroexten = "91001", '\0' <repeats 74 times>, macropriority = 1, exten
= "s\000001", '\0' <repeats 74 times>, priority = 10,
dtmfq = '\0' <repeats 79 times>, dtmff = {frametype = 0, subclass = 0,
datalen = 0, samples = 0, mallocd = 0, offset = 0, src = 0x0,
data = 0x0, delivery = {tv_sec = 0, tv_usec = 0}, prev = 0x0, next =
0x0}, pbx = 0x890bcf8, amaflags = 3,
accountcode = '\0' <repeats 19 times>, cdr = 0x88f6bc0, adsicpe = 0,
call_forward = '\0' <repeats 79 times>, zone = 0x0,
monitor = 0x0, insmpl = 0, outsmpl = 0, fin = 2969, fout = 1174,
uniqueid = "1136789367.968", '\0' <repeats 17 times>,
hangupcause = 16, varshead = {first = 0x0, last = 0x0}, callgroup = 0,
pickupgroup = 0, flags = 528, transfercapability = 0,
readq = 0x88a7a58, alertpipe = {-1, -1}, writetrans = 0x0, readtrans =
0x0, rawreadformat = 0, rawwriteformat = 0, spies = 0x88d9560,
next = 0x88ad3c0}
Notice the name. Notice, also, that the varshead.first is null. Notice,
lastly, that _softhangup == 1.
My proposed fix would be two-phase.
1) Make AST_LIST_REMOVE (and friends?) more defensive.
2) Investigate adding locking to avoid this potential race.
Regards,
Steve Davies
======================================================================
----------------------------------------------------------------------
(0099937) svnbot (reporter) - 2009-02-11 14:55
http://bugs.digium.com/view.php?id=6176#c99937
----------------------------------------------------------------------
Repository: asterisk
Revision: 174886
_U trunk/
------------------------------------------------------------------------
r174886 | tilghman | 2009-02-11 14:55:47 -0600 (Wed, 11 Feb 2009) | 19
lines
Blocked revisions 174885 via svnmerge
........
r174885 | tilghman | 2009-02-11 14:54:18 -0600 (Wed, 11 Feb 2009) | 13
lines
Restore a behavior that was recently changed, when we fixed issue
http://bugs.digium.com/view.php?id=13962
and
issue http://bugs.digium.com/view.php?id=13363 (related to issue
http://bugs.digium.com/view.php?id=6176). When a hangup occurs during a
Macro
execution in earlier 1.4, the h extension would execute within the Macro
context, whereas it was always supposed to execute only within the main
context
(where Macro was called). So this fix checks for an "h" extension in
the
deepest macro context where a hangup occurred; if it exists, that "h"
extension
executes, otherwise the main context "h" is executed.
(closes issue http://bugs.digium.com/view.php?id=14122)
Reported by: wetwired
Patches:
20090210__bug14122.diff.txt uploaded by Corydon76 (license 14)
Tested by: andrew
........
------------------------------------------------------------------------
http://svn.digium.com/view/asterisk?view=rev&revision=174886
Issue History
Date Modified Username Field Change
======================================================================
2009-02-11 14:55 svnbot Checkin
2009-02-11 14:55 svnbot Note Added: 0099937
======================================================================
More information about the asterisk-bugs
mailing list