[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
segfault if gc during backtrace
From: |
Bill Schottstaedt |
Subject: |
segfault if gc during backtrace |
Date: |
Sat, 31 Mar 2001 04:05:15 -0800 |
In Friday's CVS guile,
if you (print-enable 'source), hit an error while parsing a
procedure, then call backtrace, you can get a segfault if
the garbage collector is called during the backtrace -- the
"pstate" is freed. I can't seem to find a simple case of this bug,
but here's some info. An example backtrace:
Program received signal SIGSEGV, Segmentation fault.
0x81bd924 in scm_iprin1 (exp=1080341680, port=1080340528, pstate=0x83cf8a8)
at print.c:482
482 ENTER_NESTED_DATA (pstate, exp, circref);
(gdb) where
#0 0x81bd924 in scm_iprin1 (exp=1080341680, port=1080340528, pstate=0x83cf8a8)
at print.c:482
#1 0x81be4ca in scm_iprlist (hdr=0x8235be5 "[", exp=1080410936, tlr=93,
port=1080340528, pstate=0x83cf8a8) at print.c:907
#2 0x8197589 in display_frame_expr (hdr=0x8235be5 "[", exp=1080410936,
tlr=0x8235be3 "]", indentation=3, sport=1080340528, port=1080340984,
pstate=0x83cf8a8) at backtrace.c:353
#3 0x81977f8 in display_application (frame=1080410944, indentation=3,
sport=1080340528, port=1080340984, pstate=0x83cf8a8) at backtrace.c:392
#4 0x8197acd in display_frame (frame=1080410944, nfield=1, indentation=1,
sport=1080340528, port=1080340984, pstate=0x83cf8a8) at backtrace.c:478
#5 0x8197f47 in display_backtrace_body (a=0xbffff060) at backtrace.c:614
#6 0x81cd633 in scm_internal_catch (tag=9076,
body=0x8197bd0 <display_backtrace_body>, body_data=0xbffff060,
handler=0x819735c <display_error_handler>, handler_data=0xbffff058)
at throw.c:205
#7 0x8197fa1 in scm_display_backtrace (stack=1080684032, port=1080340984,
first=8564, depth=8564) at backtrace.c:638
#8 0x8110c6e in snd_catch_scm_error (data=0x83a2b30, tag=137016176,
throw_args=1080341080) at snd-scm.c:198
#9 0x81cd615 in scm_internal_catch (tag=9076, body=0x81cd7d8 <cwss_body>,
body_data=0xbffff240, handler=0x8110704 <snd_catch_scm_error>,
handler_data=0x83a2b30) at throw.c:200
#10 0x81cd829 in scm_internal_stack_catch (tag=9076,
body=0x811125c <eval_file_wrapper>, body_data=0x83a2a18,
handler=0x8110704 <snd_catch_scm_error>, handler_data=0x83a2b30)
at throw.c:330
#11 0x8110e7d in snd_internal_stack_catch (tag=9076,
body=0x811125c <eval_file_wrapper>, body_data=0x83a2a18,
handler=0x8110704 <snd_catch_scm_error>, handler_data=0x83a2b30)
at snd-scm.c:268
#12 0x8110ee1 in snd_catch_any (body=0x811125c <eval_file_wrapper>,
body_data=0x83a2a18, caller=0x83a2b30 "(load \"f.scm\")") at snd-scm.c:283
#13 0x8111ca3 in snd_load_file (filename=0xbffffb8e "f.scm") at snd-scm.c:657
#14 0x80f5e56 in handle_next_startup_arg (ss=0x82e61c0, auto_open_ctr=1,
auto_open_file_names=0xbffffa68, with_title=0) at snd-main.c:678
#15 0x816293b in startup_funcs (context=0x832b118) at snd-xmain.c:463
#16 0x401e8391 in ?? ()
#17 0x401e85e5 in ?? ()
#18 0x401ddfda in ?? ()
#19 0x8164dbd in snd_doit (ss=0x82e61c0, argc=3, argv=0xbffffa64)
at snd-xmain.c:990
#20 0x810bcea in snd_main (argc=3, argv=0xbffffa64) at snd.c:280
#21 0x81a7dcd in gh_launch_pad (closure=0x810b2e8, argc=3, argv=0xbffffa64)
at gh_init.c:60
#22 0x81af86e in invoke_main_func (body_data=0xbffff9a0) at init.c:633
#23 0x81af830 in scm_boot_guile_1 (base=0xbffff99c, closure=0xbffff9a0)
at init.c:613
#24 0x81af594 in scm_boot_guile (argc=3, argv=0xbffffa64,
main_func=0x81a7dbc <gh_launch_pad>, closure=0x810b2e8) at init.c:439
#25 0x81a7df9 in gh_enter (argc=3, argv=0xbffffa64,
c_main_prog=0x810b2e8 <snd_main>) at gh_init.c:70
#26 0x810bd09 in main (argc=3, argv=0xbffffa64) at snd.c:292
#27 0x4046eb65 in ?? ()
(gdb) p pstate->ref_stack
$1 = (SCM *) 0x95959595
(gdb) p pstate->fancyp
$6 = 2509608341
where the actual problem is that in ENTER_NESTED_DATA:
if (SCM_EQ_P (pstate->ref_stack[i], (obj))) \
pstate->ref_stack no longer exists (and it appears that pstate itself
has been freed).
Now to try to find where this field got clobbered,
I added this in print.c:
static scm_print_state *ps;
SCM *what_is_pstate(void) {if (ps) return(ps->ref_stack); else
return(NULL);}
and this just before the code in the question:
ps = pstate;
code = scm_unmemocopy (code,
SCM_EXTEND_ENV (SCM_CAR (code),
SCM_EOL,
env));
fprintf(stderr,"nest %p",pstate->ref_stack);
ENTER_NESTED_DATA (pstate, exp, circref);
and in eval.c this:
loop:
fprintf(stderr,"loop: %p", what_is_pstate());
while (SCM_CELLP (x = SCM_CDR (x)) && SCM_ECONSP (x))
{
fprintf(stderr,"... %p", what_is_pstate());
if (SCM_ISYMP (SCM_CAR (x)))
/* skip body markers */
continue;
SCM_SETCDR (z, unmemocar (scm_cons (unmemocopy (SCM_CAR (x), env),
SCM_UNSPECIFIED),
env));
z = SCM_CDR (z);
}
and in gc.c had scm_igc (ca line 1003, at the start) print out:
fprintf (stderr, "gc: %s %p\n", what, what_is_pstate());
then ran the segfault case and got:
[...]
loop: 0x83cf8f8... 0x83cf8f8... 0x83cf8f8... 0x83cf8f8... 0x83cf8f8...
0x83cf8f8gc: cells 0x83cf8f8
0x95959595 ... 0x95959595... 0x95959595... 0x95959595... 0x95959595...
0x95959595... 0x95959595...
[...]
(I think the 0x95... business happens because I'm running with -lmcheck).
If I add this at line 567 in backtrace.c (just after the scm_make_print_state):
scm_protect_object(print_state);
the program works fine, but of course that isn't the "right thing".
- segfault if gc during backtrace,
Bill Schottstaedt <=