Ticket #717 (closed bug: fixed)

Opened 5 years ago

Last modified 5 years ago

parrot_config segfaults when invoked with the --dump option

Reported by: Util Owned by: Util
Priority: normal Milestone:
Component: none Version: trunk
Severity: high Keywords: GC parrot_config dump
Cc: Language: perl6
Patch status: Platform:

Description

Summary

parrot_config segfaults when invoked with the --dump option. This occurs in any form of invocation:

  • ./parrot_config --dump
  • ./parrot parrot_config.pbc --dump
  • ./parrot tools/util/parrot-config.pir --dump

When the ./parrot variants are also invoked with the -G option (to disable garbage collection), the output completes normally.

This ticket is flagged as language:perl6 because Rakudo users are reporting "Reading configuration information from parrot/parrot_config ...Died at Configure.pl line 104." Rakudo's Configure.pl is failing when it tries to run ./parrot_config --dump.

Research

(I think) I traced the problem to the use of a "fake" STRING in Parrot_io_write() in src/io/api.c. My GC skills were not strong enough to fix the issue, but I wrote a work-around patch that reduces the use of "fake" to the point that parrot_config --dump succeeds. The patch optimizes the common case of the single newline that say emits.

Note: I do not recommend that the patch be applied to SVN trunk. It is a workaround only.

Original report

trimmed from  http://irclog.perlgeek.de/parrot/2009-05-19 :

18:25 Util          With Parrot r38941, on darwin, plus one patch that does not affect config, running `./parrot parrot_config.pbc --dump` prints the first 12 lines, then "Bus error".
18:25 Util          Disabling GC allows all lines to print. `./parrot -G parrot_config.pbc --dump`.
18:25 Util          My build passes all tests in `make test`.
18:25 Util          BTW, I do not see anywhere that we exercise parrot_config in t/*.
18:25 Util          Can anyone duplicate the issue?
18:26 Whiteknight   davidfetter: Nobody that I know of
18:27 jonathan      Util: Any chance of a backtrace?
18:28 Whiteknight   Util: and what's the patch?
18:29 Util          Whiteknight: patch is the latest in my uncommitted pbc_to_exe efforts. That is why I am invoking with the parrot+.pbc call, instead of `./parrot_config`
18:34 nopaste       "Util" at 68.191.99.24 pasted "parrot_config.pbc backtrace" (94 lines) at http://nopaste.snit.ch/16609
18:38 jonathan      Util: Oh gee, it's actually segfaulting *inside* the GC...
18:39 jonathan      holy s**t...doing a write goes through 3 layers of PCCINVOKES?!
18:39 Whiteknight   somewhere it looks like a Context is holding a bogus pointer, Unused pointers should be NULL'd in Contexts
18:40 jonathan      Whiteknight: Yeah.
18:40 Whiteknight   yeah, the IO system really utilizes it's PMCs
18:40 Whiteknight   All the more reason to (1) get PCC optimized and (2) to get asynchronous IO working
18:40 jonathan      Whiteknight: I'm wondering if the something inside PCCINVOKE maybe doesn't init the outer pointer or something...
18:41 chromatic     That could be a context change I committed the other day to avoid calloc.
18:41 Whiteknight   weird that it would only show up in such a particular stack trace
18:41 jonathan      Whiteknight: We probably often don't call 3 levels of PCCINVOKES...
18:42 chromatic     It makes sense to me.  If there's an uninitialized struct member....
18:42 Whiteknight   0xbffff570, is that a protected address on darwin?
18:42 jonathan      chromatic: I can only guess it normally gets initialized when doing stuff in PIR and the PCCINVOKE path leaves a junk value.
18:42 chromatic     That could be.
18:42 Whiteknight   or is does that PMC itself contain the bad pointer?
18:44 Whiteknight   no, I take that back, 0xbffff570 is the bad address
18:45 jonathan      oh ouch
18:45 jonathan      for (i = 0; i < ctx->n_regs_used[REGNO_STR]; ++i) {
18:45 jonathan      obj = (PObj *)CTX_REG_STR(ctx, i);
18:45 jonathan      if (obj)
18:45 jonathan      Parrot_gc_mark_PObj_alive(interp, obj);
18:45 jonathan      It's that which is passing the bad pointer, it seems.
18:45 jonathan      (Line 124 is that last one)
19:10 Util          parrot_config issue update - I tried a fresh checkout, with no patches. It has the exact same problem.

Backtrace

originally submitted as  http://nopaste.snit.ch/16609 :

$ gdb ./parrot_config
GNU gdb 6.3.50-20050815 (Apple version gdb-696) (Sat Oct 20 18:16:54 GMT 2007)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i386-apple-darwin"...
warning: --arch option not supported in this gdb.
Reading symbols for shared libraries ........ done

(gdb) run --dump
Starting program: /Users/bruce/Perl/Parrot/Trip_20090429/rakudo/parrot/parrot_config --dump
Reading symbols for shared libraries .+.........+.+ done
-falign-functions=16 => '1'
-funit-at-a-time => '1'
-fvisibility=hidden => '1'
-maccumulate-outgoing-args => '1'
-W => '1'
-Waggregate-return => '1'
-Wall => '1'
-Wbad-function-cast => '1'
-Wc++-compat => '0'
-Wcast-align => '1'
-Wcast-qual => '1'
-Wchar-subscripts => '1'
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_PROTECTION_FAILURE at address: 0x00000001
0x01085adf in Parrot_gc_mark_PObj_alive (interp=0x500d70, obj=0xbffff570) at src/gc/api.c:137
137             else if (p->pmc_ext && PMC_metadata(p))
(gdb) bt
#0  0x01085adf in Parrot_gc_mark_PObj_alive (interp=0x500d70, obj=0xbffff570) at src/gc/api.c:137
#1  0x010f4b13 in mark_context (interp=0x500d70, ctx=0x518e20) at src/sub.c:124
#2  0x011a0700 in Parrot_Continuation_mark (interp=0x500d70, pmc=0x4e00c0) at ./src/pmc/continuation.pmc:92
#3  0x0108c8c0 in mark_special (interp=0x500d70, obj=0x4e00c0) at src/gc/mark_sweep.c:394
#4  0x01085aa3 in Parrot_gc_mark_PObj_alive (interp=0x500d70, obj=0x4e00c0) at src/gc/api.c:134
#5  0x010f49e1 in mark_context (interp=0x500d70, ctx=0x518fa0) at src/sub.c:91
#6  0x011a0700 in Parrot_Continuation_mark (interp=0x500d70, pmc=0x4e0078) at ./src/pmc/continuation.pmc:92
#7  0x0108c8c0 in mark_special (interp=0x500d70, obj=0x4e0078) at src/gc/mark_sweep.c:394
#8  0x01085aa3 in Parrot_gc_mark_PObj_alive (interp=0x500d70, obj=0x4e0078) at src/gc/api.c:134
#9  0x010f49e1 in mark_context (interp=0x500d70, ctx=0x519090) at src/sub.c:91
#10 0x011a0700 in Parrot_Continuation_mark (interp=0x500d70, pmc=0x4e0048) at ./src/pmc/continuation.pmc:92
#11 0x0108c8c0 in mark_special (interp=0x500d70, obj=0x4e0048) at src/gc/mark_sweep.c:394
#12 0x01085aa3 in Parrot_gc_mark_PObj_alive (interp=0x500d70, obj=0x4e0048) at src/gc/api.c:134
#13 0x010f49e1 in mark_context (interp=0x500d70, ctx=0x519160) at src/sub.c:91
#14 0x011a0700 in Parrot_Continuation_mark (interp=0x500d70, pmc=0x4e0000) at ./src/pmc/continuation.pmc:92
#15 0x0108c8c0 in mark_special (interp=0x500d70, obj=0x4e0000) at src/gc/mark_sweep.c:394
#16 0x01085aa3 in Parrot_gc_mark_PObj_alive (interp=0x500d70, obj=0x4e0000) at src/gc/api.c:134
#17 0x010f49e1 in mark_context (interp=0x500d70, ctx=0x519260) at src/sub.c:91
#18 0x0108d0bb in Parrot_gc_trace_root (interp=0x500d70, trace=GC_TRACE_FULL) at src/gc/mark_sweep.c:129
#19 0x010893a2 in gc_ms_trace_active_PMCs (interp=0x500d70, trace=GC_TRACE_FULL) at src/gc/gc_ms.c:285
#20 0x010894d4 in gc_ms_mark_and_sweep (interp=0x500d70, flags=1) at src/gc/gc_ms.c:206
#21 0x01086c12 in Parrot_gc_mark_and_sweep (interp=0x500d70, flags=1) at src/gc/api.c:717
#22 0x010897a6 in gc_ms_more_traceable_objects (interp=0x500d70, pool=0x501160) at src/gc/gc_ms.c:373
#23 0x01089904 in gc_ms_get_free_object (interp=0x500d70, pool=0x501160) at src/gc/gc_ms.c:436
#24 0x010862bc in Parrot_gc_new_pmc_header (interp=0x500d70, flags=1024) at src/gc/api.c:230
#25 0x010eb04c in get_new_pmc_header (interp=0x500d70, base_type=25, flags=1024) at src/pmc.c:295
#26 0x010eb157 in pmc_new (interp=0x500d70, base_type=25) at src/pmc.c:108
#27 0x011f8e16 in Parrot_FileHandle_nci_is_closed (interp=0x500d70, pmc=0xf9f68) at /Users/bruce/Perl/Parrot/Trip_20090429/rakudo/parrot/tools/build/../../lib/Parrot/Pmc2c/PCCMETHOD.pm:425
#28 0x011a39de in Parrot_NCI_invoke (interp=0x500d70, pmc=0xf9f68, next=0x0) at ./src/pmc/nci.pmc:335
#29 0x01098109 in Parrot_PCCINVOKE (interp=0x500d70, pmc=0x4e6258, method_name=0x20028a8, signature=0x128f260 "->I") at src/call/pcc.c:2870
#30 0x0117e9f5 in Parrot_io_is_closed (interp=0x500d70, pmc=0x4e6258) at src/io/api.c:222
#31 0x011831e2 in Parrot_io_flush_filehandle (interp=0x500d70, pmc=0x4e6258) at src/io/filehandle.c:738
#32 0x011fa61e in Parrot_FileHandle_nci_flush (interp=0x500d70, pmc=0xf9ef0) at ./src/pmc/filehandle.pmc:465
#33 0x011a39de in Parrot_NCI_invoke (interp=0x500d70, pmc=0xf9ef0, next=0x0) at ./src/pmc/nci.pmc:335
#34 0x01098109 in Parrot_PCCINVOKE (interp=0x500d70, pmc=0x4e6258, method_name=0x2002884, signature=0x128f264 "->") at src/call/pcc.c:2870
#35 0x0117eab5 in Parrot_io_flush (interp=0x500d70, pmc=0x4e6258) at src/io/api.c:245
#36 0x01180fb5 in Parrot_io_write_buffer (interp=0x500d70, filehandle=0x4e6258, s=0xbffff570) at src/io/buffer.c:626
#37 0x011fad00 in Parrot_FileHandle_nci_puts (interp=0x500d70, pmc=0xf9ec0) at ./src/pmc/filehandle.pmc:518
#38 0x011a39de in Parrot_NCI_invoke (interp=0x500d70, pmc=0xf9ec0, next=0x0) at ./src/pmc/nci.pmc:335
#39 0x01098109 in Parrot_PCCINVOKE (interp=0x500d70, pmc=0x4e6258, method_name=0x20027f4, signature=0x128e004 "S->I") at src/call/pcc.c:2870
#40 0x0117ece8 in Parrot_io_putps (interp=0x500d70, pmc=0x4e6258, s=0xbffff570) at src/io/api.c:474
#41 0x0117edef in Parrot_io_write (interp=0x500d70, pmc=0x4e6258, buffer=0x127b588, length=1) at src/io/api.c:327
#42 0x0117f1f1 in Parrot_io_puts (interp=0x500d70, pmc=0x4e6258, s=0x127b588 "\n") at src/io/api.c:449
#43 0x0101fa8f in Parrot_say_sc (cur_opcode=0x5181bc, interp=0x500d70) at src/ops/io.ops:238
#44 0x010edea3 in runops_slow_core (interp=0x500d70, pc=0x5181bc) at src/runcore/cores.c:462
#45 0x010ed0a5 in runops_int (interp=0x500d70, offset=3) at src/runcore/main.c:981
#46 0x0109ab31 in runops (interp=0x500d70, offs=3) at src/call/ops.c:107
#47 0x0109adf7 in runops_args (interp=0x500d70, sub=0x4e5fb8, obj=0x20352e0, meth_unused=0x0, sig=0x127a32c "vP", ap=0xbffff79c "?_N") at src/call/ops.c:256
#48 0x0109bc39 in Parrot_runops_fromc_args (interp=0x500d70, sub=0x4e5fb8, sig=0x127a32c "vP") at src/call/ops.c:325
#49 0x010788be in Parrot_runcode (interp=0x500d70, argc=2, argv=0xbffff870) at src/embed.c:1009
#50 0x00002270 in main (argc=2, argv=0xbffff870) at parrot_config.c:96
(gdb) l
132
133             if (PObj_is_special_PMC_TEST(obj))
134                 mark_special(interp, p);
135
136     #  ifndef NDEBUG
137             else if (p->pmc_ext && PMC_metadata(p))
138                 fprintf(stderr, "GC: error obj %p (%s) has properties\n",
139                         (void *)p, (char*)p->vtable->whoami->strstart);
140     #  endif
141         }
(gdb)

OTHER REPORTS

  • 2009-05-26, in email to perl6-users, Nelo Onyiah reported the issue.
  • 2009-05-28, in #perl6, ZuLuuuuuu reported the issue on Ubuntu 9.04. I assume his rev was r39025, since it was the PARROT_REVISION in Rakudo at the time. He also reported that the problem was resolved in r39219.

Attachments

fake_string_newline_optimization.patch Download (0.8 KB) - added by Util 5 years ago.
Workaround patch

Change History

Changed 5 years ago by Util

Workaround patch

Changed 5 years ago by NotFound

Changed say to emit the newline using putps instead of puts in r39223. This is not a workaround for this problem, is a change for better.

IMO the problem with the implementation of Parrot_io_write must not be fixed by tweaking the gc, it must be fixed by implementing Parrot_io_write in a sane way without abusing of string internals.

Changed 5 years ago by jkeenan

Util,

I have used parrot_config --dump several times today on both Darwin/PPC and Linux/i386 and have experienced no problems.

Is this still segfaulting for you? If not, is the ticket closable?

Thank you very much.
kid51

Changed 5 years ago by Util

  • owner set to Util

Changed 5 years ago by Util

  • status changed from new to closed
  • resolution set to fixed

Thanks to kid51++ for the reminder.

The change in r39223 by NotFound resolved the original segfaults. The underlying cause of the segfaults (use of a "fake" STRING in Parrot_io_write) remains unfixed, but it no longer causes any user-visible problems.

The problematic Parrot_io_write appears to be a good candidate for deprecation. Therefore, I will open a ticket regarding that, rather than keep this ticket open for a "fake" STRING fix.

Note: See TracTickets for help on using tickets.