ivmai / bdwgc

The Boehm-Demers-Weiser conservative C/C++ Garbage Collector (bdwgc, also known as bdw-gc, boehm-gc, libgc)
https://www.hboehm.info/gc/
Other
2.98k stars 407 forks source link

Unexpected bus error or list reversal failure in gctest/x86 compiled with MARK_BIT_PER_OBJ #177

Closed ivmai closed 6 years ago

ivmai commented 7 years ago

Switched to incremental mode Emulating dirty bits with mprotect/signals Unexpected bus error or segmentation fault /bin/bash: line 5: 15442 Segmentation fault (core dumped) ${dir}$tst FAIL: gctest

Build: https://travis-ci.org/ivmai/bdwgc/jobs/256171109 Source: 348bc2b (latest master) Compiler: gcc-4.6 (also reproduced with gcc-4.8) Host: Ubuntu/x64 (32 cores) How to reproduce:

ivmai commented 7 years ago

Also one gctest run produced the following: Switched to incremental mode Emulating dirty bits with mprotect/signals List reversal produced incorrect list - collector is broken Test failed

ivmai commented 7 years ago

Another gctest run showed: Switched to incremental mode Emulating dirty bits with mprotect/signals GC Warning: Failed to expand heap by 8388608 bytes GC Warning: Failed to expand heap by 8388608 bytes ... GC Warning: Failed to expand heap by 8388608 bytes Too many heap sections: Increase MAXHINCR or MAX_HEAP_SECTS

ivmai commented 7 years ago

Reproduced on another configuration: ./configure --enable-werror --disable-gcj-support --disable-thread-local-alloc --disable-disclaim --enable-gc-assertions && make -j check CFLAGS_EXTRA="-m64 -D MARK_BIT_PER_OBJ -O0 -g -DNTHREADS=0"

Not reproduced without MARK_BIT_PER_OBJ, or GC_enable_incremental, or without GC_THREADS, or with GC_MARKERS=1.

ivmai commented 7 years ago

Also one gctest run produced the following: Switched to incremental mode Emulating dirty bits with mprotect/signals Caught signal 11: looping in handler

Caused by the following code in alloc8bytes: my_free_list = my_free_list_ptr; my_free_list_ptr = GC_NEXT(my_free_list); // my_free_list == 1

Or, once, it was caused by SIGSEGV in GC_array_mark_proc: hdr * hhdr = HDR(addr); // addr is valid size_t sz = hhdr -> hb_sz; // hhdr == 4 Call stack: # 3 0x00007f4226451f63 in GC_array_mark_proc (addr=0x1d57000, mark_stack_ptr=0x212a670, mark_stack_limit=0x216a000, env=0) at extra/../typd_mlc.c:482 # 4 0x00007f422644c24b in GC_mark_from (mark_stack_top=0x212a670, mark_stack=0x212a000, mark_stack_limit=0x216a000) at extra/../mark.c:784 # 5 0x00007f422644b88c in GC_mark_some ( cold_gc_frame=0x7ffc692edd70 "\300\335.i\374\177") at extra/../mark.c:409 # 6 0x00007f42264429d1 in GC_stopped_mark ( stop_func=0x7f4226441a00 ) at extra/../alloc.c:707 # 7 0x00007f42264420c4 in GC_maybe_gc () at extra/../alloc.c:402 # 8 0x00007f422644269c in GC_collect_a_little_inner (n=1) at extra/../alloc.c:581 # 9 0x00007f4226444387 in GC_allocobj (gran=2, kind=1) at extra/../alloc.c:1432 # 10 0x00007f422643db49 in GC_generic_malloc_inner (lb=24, k=1)

ivmai commented 7 years ago

Cygwin/x86: gcc -I include -I libatomic_ops/src -D GC_ASSERTIONS -D GC_THREADS -D NTHREADS=0 -D MARK_BITS_PER_OBJ -O0 -g tests/test.c extra/gc.c

Result: Assertion failure: extra/../reclaim.c:427 GC_ASSERT(sz * hhdr -> hb_n_marks <= HBLKSIZE);

ivmai commented 7 years ago

Changing in GC_set_hdr_marks hhdr -> hb_n_marks = n_marks - 1; to hhdr -> hb_n_marks = n_marks;

Solved issue observed on Cygwin/x86 and seems to fix this configuration (./configure --enable-werror --disable-gcj-support --disable-thread-local-alloc --disable-parallel-mark --disable-disclaim --enable-gc-assertions && make -j check CFLAGS_EXTRA="-m64 -D MARK_BIT_PER_OBJ -O0 -g -DNTHREADS=0") but not initially reported configuration (both -m32 and -m64 cases).

ivmai commented 7 years ago

Reproduced the failure (list reversal) and SIGSEGV (during hhdr dereference) with ASan/MSan/UBSan. The first two give no error message, UBSan produces useless message:

Emulating dirty bits with mprotect/signals typd_mlc.c:482:25: runtime error: member access within misaligned address 0x0000 00000002 for type 'hdr' (aka 'struct hblkhdr'), which requires 8 byte alignment 0x000000000002: note: pointer points here \

ivmai commented 6 years ago

Seems to be related. Build: https://travis-ci.org/ivmai/bdwgc/jobs/339424046 (same config) Source: master gctest.log: GC Warning: getcontext failed: using another register retrieval method... Switched to incremental mode Emulating dirty bits with mprotect/signals GC Warning: getcontext failed: using another register retrieval method... GC Warning: getcontext failed: using another register retrieval method... ...

ivmai commented 6 years ago

I can't reproduce anything listed above using the latest master except for the following case.

Source: 2add709 (latest master) Host: Ubuntu/x64 How to reproduce:

Alternative configuration: ./configure --enable-werror --disable-handle-fork && make -j check CFLAGS_EXTRA="-m32 -D MARK_BIT_PER_OBJ"

Output: Switched to incremental mode Emulating dirty bits with mprotect/signals List reversal produced incorrect list - collector is broken Test failed

ivmai commented 6 years ago

SIGSEGV occurred.

Source: 2add709 (latest master) Host: Ubuntu/x64 ./configure --disable-handle-fork && make -j check CFLAGS_EXTRA="-m32 -D MARK_BIT_PER_OBJ -D NTHREADS=300 -O0"

Stack trace: # 0 GC_write_fault_handler (sig=11, si=0xdad5d98c, raw_sc=0xdad5da0c) at extra/../os_dep.c:3358 # 1 # 2 0xf7f9c043 in GC_array_mark_proc (addr=0x95e3000, mark_stack_ptr=0x89e1018, mark_stack_limit=0x89e9000, env=0) at extra/../typd_mlc.c:483 // hhdr = (hdr *)0x1 # 3 0xf7f9757f in GC_mark_from (mark_stack_top=0x89e1018, mark_stack=0x89e1000, mark_stack_limit=0x89e9000) at extra/../mark.c:782 # 4 0xf7f97e7d in GC_do_local_mark (local_mark_stack=0x89e1000, local_top=0x89e1018) at extra/../mark.c:1076 # 5 0xf7f981a4 in GC_mark_local (local_mark_stack=0x89e1000, id=0) at extra/../mark.c:1207 # 6 0xf7f9826f in GC_do_parallel_mark () at extra/../mark.c:1231 # 7 0xf7f96e1a in GC_mark_some ( cold_gc_frame=0xdad5e068 "\270\340\325?\364\370\367h\340\325", <incomplete sequence \332>) at extra/../mark.c:390 # 8 0xf7f8f48c in GC_stopped_mark (stop_func=0xf7f8e89d )

ivmai commented 6 years ago

List reversal produced incorrect list - collector is broken

Build: https://travis-ci.org/ivmai/bdwgc/jobs/372163105 Source: latest master (b76c7a0)

ivmai commented 6 years ago

Reproduced on latest master. gcc -O0 -g -I include -D MARK_BIT_PER_OBJ -D ALL_INTERIOR_POINTERS -D USE_MMAP -D GC_ASSERTIONS -D GC_DISABLE_INCREMENTAL -D NO_TYPED_TEST -m32 tests/test.c extra/gc.c exec a.out 100 times