C++ in jemalloc
Mark Millard
markmi at dsl-only.net
Sat Oct 7 09:18:41 UTC 2017
[I'm separately listing backtrace information and related
information from one of core dumps and going back through
the details to see if they seem to be as they were back
then. Read only if you care. It does look the same as I
found back then if I remember right. I reach the same
conclusion I reached back then anyway. I give evidence
in the below.]
On 2017-Oct-7, at 1:10 AM, Mark Millard <markmi at dsl-only.net> wrote:
> [I'm adding examples with output from clang -v since it explicitly shows
> the path used for ld and such.]
>
> On 2017-Oct-7, at 12:58 AM, Mark Millard <markmi at dsl-only.net> wrote:
>
>> On 2017-Oct-6, at 11:42 PM, Roman Divacky <rdivacky at vlakno.cz> wrote:
>>
>>> Just to clarify my not agreeing with Mark regarding EH on ppc64.
>>>
>>> Last time I tried to fix ppc64 exceptions handling as generated by clang
>>> it turned out that simply using gnu ld from ports fixes the issue.
>>>
>>> For details see:
>>> https://lists.freebsd.org/pipermail/freebsd-toolchain/2017-May/002961.html
>>
>> Unfortunately my experiments failed to confirm this. Repeating
>> them now under head -r324071 and ports -r450478 :
>>
>> # more exception_test.cpp
>> #include <exception>
>>
>> int main(void)
>> {
>> try { throw std::exception(); }
>> catch (std::exception& e) {}
>> return 0;
>> }
>>
>> # clang++ -B /usr/local/powerpc64-freebsd/bin -std=c++14 -g -O2 exception_test.cpp
>>
>> # ./a.out
>> Segmentation fault (core dumped)
>>
>> # clang++ -B /usr/local/powerpc64-freebsd/bin -std=c++11 -g exception_test.cpp
>>
>> # ./a.out
>> Segmentation fault (core dumped)
>
> # clang++ -v -B /usr/local/powerpc64-freebsd/bin -std=c++11 -g exception_test.cpp
> FreeBSD clang version 5.0.0 (tags/RELEASE_500/final 312559) (based on LLVM 5.0.0svn)
> Target: powerpc64-unknown-freebsd12.0
> Thread model: posix
> InstalledDir: /usr/bin
> "/usr/bin/clang++" -cc1 -triple powerpc64-unknown-freebsd12.0 -emit-obj -mrelax-all -disable-free -main-file-name exception_test.cpp -mrelocation-model pic -pic-level 2 -mthread-model posix -mdisable-fp-elim -masm-verbose -mconstructor-aliases -target-cpu ppc64 -mfloat-abi hard -v -dwarf-column-info -debug-info-kind=standalone -dwarf-version=2 -debugger-tuning=gdb -resource-dir /usr/lib/clang/5.0.0 -internal-isystem /usr/include/c++/v1 -std=c++11 -fdeprecated-macro -fdebug-compilation-dir /root/c_tests -ferror-limit 19 -fmessage-length 200 -fno-signed-char -fobjc-runtime=gnustep -fcxx-exceptions -fexceptions -fdiagnostics-show-option -fcolor-diagnostics -o /tmp/exception_test-ba79a4.o -x c++ exception_test.cpp
> clang -cc1 version 5.0.0 based upon LLVM 5.0.0svn default target powerpc64-unknown-freebsd12.0
> #include "..." search starts here:
> #include <...> search starts here:
> /usr/include/c++/v1
> /usr/lib/clang/5.0.0/include
> /usr/include
> End of search list.
> "/usr/local/powerpc64-freebsd/bin/ld" --eh-frame-hdr -dynamic-linker /libexec/ld-elf.so.1 --enable-new-dtags -o a.out /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/crtbegin.o -L/usr/lib /tmp/exception_test-ba79a4.o -lc++ -lm -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/crtend.o /usr/lib/crtn.o
>
> # ./a.out
> Segmentation fault (core dumped)
>
>
>> # ls -lt /usr/local/powerpc64-freebsd/bin
>> total 56704
>> lrwxr-xr-x 1 root wheel 32 Jul 2 19:27 size -> ../../bin/powerpc64-freebsd-size
>> -r-xr-xr-x 4 root wheel 7072791 Jul 2 19:27 ld
>> -r-xr-xr-x 4 root wheel 7072791 Jul 2 19:27 ld.bfd
>> -r-xr-xr-x 2 root wheel 6881822 Jul 2 19:27 as
>> -r-xr-xr-x 2 root wheel 6128889 Jul 2 19:27 strip
>> -r-xr-xr-x 2 root wheel 5253417 Jul 2 19:27 nm
>> -r-xr-xr-x 2 root wheel 1284139 Jul 2 19:27 readelf
>> -r-xr-xr-x 2 root wheel 6128882 Jul 2 19:27 objcopy
>> -r-xr-xr-x 2 root wheel 5384166 Jul 2 19:27 ranlib
>> -r-xr-xr-x 2 root wheel 5384159 Jul 2 19:27 ar
>> -r-xr-xr-x 2 root wheel 6914775 Jul 2 19:27 objdump
>>
>> # clang++ -B /usr/local/powerpc64-portbld-freebsd12.0/bin/ -std=c++14 -g -O2 exception_test.cpp
>>
>> # ./a.out
>> Segmentation fault (core dumped)
>
> # clang++ -v -B /usr/local/powerpc64-portbld-freebsd12.0/bin/ -std=c++14 -g -O2 exception_test.cpp
> FreeBSD clang version 5.0.0 (tags/RELEASE_500/final 312559) (based on LLVM 5.0.0svn)
> Target: powerpc64-unknown-freebsd12.0
> Thread model: posix
> InstalledDir: /usr/bin
> "/usr/bin/clang++" -cc1 -triple powerpc64-unknown-freebsd12.0 -emit-obj -disable-free -main-file-name exception_test.cpp -mrelocation-model pic -pic-level 2 -mthread-model posix -mdisable-fp-elim -masm-verbose -mconstructor-aliases -target-cpu ppc64 -mfloat-abi hard -v -dwarf-column-info -debug-info-kind=standalone -dwarf-version=2 -debugger-tuning=gdb -resource-dir /usr/lib/clang/5.0.0 -internal-isystem /usr/include/c++/v1 -O2 -std=c++14 -fdeprecated-macro -fdebug-compilation-dir /root/c_tests -ferror-limit 19 -fmessage-length 200 -fno-signed-char -fobjc-runtime=gnustep -fcxx-exceptions -fexceptions -fdiagnostics-show-option -fcolor-diagnostics -vectorize-loops -vectorize-slp -o /tmp/exception_test-3ebf72.o -x c++ exception_test.cpp
> clang -cc1 version 5.0.0 based upon LLVM 5.0.0svn default target powerpc64-unknown-freebsd12.0
> #include "..." search starts here:
> #include <...> search starts here:
> /usr/include/c++/v1
> /usr/lib/clang/5.0.0/include
> /usr/include
> End of search list.
> "/usr/local/powerpc64-portbld-freebsd12.0/bin/ld" --eh-frame-hdr -dynamic-linker /libexec/ld-elf.so.1 --enable-new-dtags -o a.out /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/crtbegin.o -L/usr/lib /tmp/exception_test-3ebf72.o -lc++ -lm -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/crtend.o /usr/lib/crtn.o
>
> # ./a.out
> Segmentation fault (core dumped)
>
>> # clang++ -B /usr/local/powerpc64-portbld-freebsd12.0/bin/ -std=c++11 -g exception_test.cpp
>>
>> # ./a.out
>> Segmentation fault (core dumped)
>>
>>
>> # ls -lt /usr/local/powerpc64-portbld-freebsd12.0/bin/
>> total 363584
>> -r-xr-xr-x 4 root wheel 59993201 Jul 2 23:44 ld
>> -r-xr-xr-x 4 root wheel 59993201 Jul 2 23:44 ld.bfd
>> -r-xr-xr-x 2 root wheel 29843304 Jul 2 23:44 as
>> -r-xr-xr-x 2 root wheel 29046519 Jul 2 23:44 strip
>> -r-xr-xr-x 2 root wheel 28207257 Jul 2 23:44 nm
>> -r-xr-xr-x 2 root wheel 1178483 Jul 2 23:44 readelf
>> -r-xr-xr-x 1 root wheel 28329180 Jul 2 23:44 dlltool
>> -r-xr-xr-x 2 root wheel 29046512 Jul 2 23:44 objcopy
>> -r-xr-xr-x 2 root wheel 28334599 Jul 2 23:44 ranlib
>> -r-xr-xr-x 2 root wheel 28334592 Jul 2 23:44 ar
>> -r-xr-xr-x 2 root wheel 49540244 Jul 2 23:44 objdump
[Note: I used /usr/libexec/gdb because /usr/local/bin/gdb
core dumps for this. powerpc64 is an example of the
devel/gdb port currently being worse than the system gdb
in various cases.]
# /usr/libexec/gdb a.out /var/crash/a.out.12775.core
GNU gdb 6.1.1 [FreeBSD]
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 "powerpc64-marcel-freebsd"...
Core was generated by `./a.out'.
Program terminated with signal 11, Segmentation fault.
Reading symbols from /usr/lib/libc++.so.1...Reading symbols from /usr/lib/debug//usr/lib/libc++.so.1.debug...done.
done.
. . .
Loaded symbols for /libexec/ld-elf.so.1
#0 0x0000000050530c20 in _Unwind_SetGR (context=<value optimized out>, index=<value optimized out>, val=1342447712) at unwind-dw2-fde.h:162
162 {
(gdb) bt
#0 0x0000000050530c20 in _Unwind_SetGR (context=<value optimized out>, index=<value optimized out>, val=1342447712) at unwind-dw2-fde.h:162
#1 0x0000000050190194 in __gxx_personality_v0 (version=<value optimized out>, actions=<value optimized out>, exceptionClass=<value optimized out>, exceptionObject=0x50042060,
context=0xffffffffffffcc70) at /usr/src/contrib/libcxxrt/exception.cc:1203
#2 0x0000000050531a60 in _Unwind_RaiseException_Phase2 (exc=0x50042060, context=0xffffffffffffcc70) at unwind.inc:66
#3 0x0000000050531548 in _Unwind_RaiseException (exc=<value optimized out>) at unwind.inc:135
#4 0x000000005018f4f4 in __cxa_throw (thrown_exception=<value optimized out>, tinfo=<value optimized out>, dest=<value optimized out>) at /usr/src/contrib/libcxxrt/exception.cc:774
#5 0x0000000010000d74 in main () at exception_test.cpp:5
#6 0x0000000010000ae8 in _start (argc=1342447624, argv=0x50042060, env=0xffffffffffffcc70, obj=<value optimized out>, cleanup=<value optimized out>, ps_strings=<value optimized out>)
at /usr/src/lib/csu/powerpc64/crt1.c:94
#7 0x0000000050017b70 in .text () at /usr/src/libexec/rtld-elf/powerpc64/rtld_start.S:104
. . .
__gxx_personality_v0 was trying to execute:
_Unwind_SetGR(context, __builtin_eh_return_data_regno(0),
reinterpret_cast<unsigned long>(exceptionObject));
That was part of the sequence:
. . .
_Unwind_SetIP(context, reinterpret_cast<unsigned long>(action.landing_pad));
_Unwind_SetGR(context, __builtin_eh_return_data_regno(0),
reinterpret_cast<unsigned long>(exceptionObject));
_Unwind_SetGR(context, __builtin_eh_return_data_regno(1), selector);
return _URC_INSTALL_CONTEXT;
So it died trying to use the CFA information for one of
the scratch registers, the one used for the "exceptionObject".
The details are:
inline void
_Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
{
int size;
void *ptr;
index = DWARF_REG_TO_UNWIND_COLUMN (index);
gcc_assert (index < (int) sizeof(dwarf_reg_size_table));
size = dwarf_reg_size_table[index];
if (_Unwind_IsExtendedContext (context) && context->by_value[index])
{
context->reg[index] = (void *) (_Unwind_Internal_Ptr) val;
return;
}
ptr = context->reg[index];
if (size == sizeof(_Unwind_Ptr))
* (_Unwind_Ptr *) ptr = val;
else
{
gcc_assert (size == sizeof(_Unwind_Word));
* (_Unwind_Word *) ptr = val;
}
}
Note: DWARF_REG_TO_UNWIND_COLUMN leaves the index value
unchanged for the value involved. I'll not provide the
evidence here.
Breakpoint 1, main () at exception_test.cpp:5
5 try { throw std::exception(); }
(gdb) br _Unwind_SetGR
Breakpoint 2 at 0x50530bbc
(gdb) c
Continuing.
Breakpoint 2, _Unwind_SetGR (context=0xffffffffffffcc30, index=3, val=1342447712) at /usr/src/gnu/lib/libgcc/../../../contrib/gcc/unwind-dw2.c:207
207 index = DWARF_REG_TO_UNWIND_COLUMN (index);
Current language: auto; currently minimal
(gdb) bt
#0 _Unwind_SetGR (context=0xffffffffffffcc30, index=3, val=1342447712) at /usr/src/gnu/lib/libgcc/../../../contrib/gcc/unwind-dw2.c:207
#1 0x0000000050190194 in __gxx_personality_v0 (version=<value optimized out>, actions=<value optimized out>, exceptionClass=<value optimized out>, exceptionObject=0x50042060,
context=0xffffffffffffcc30) at /usr/src/contrib/libcxxrt/exception.cc:1203
#2 0x0000000050531a60 in _Unwind_RaiseException_Phase2 (exc=0x50042060, context=0xffffffffffffcc30) at unwind.inc:66
#3 0x0000000050531548 in _Unwind_RaiseException (exc=<value optimized out>) at unwind.inc:135
#4 0x000000005018f4f4 in __cxa_throw (thrown_exception=<value optimized out>, tinfo=<value optimized out>, dest=<value optimized out>) at /usr/src/contrib/libcxxrt/exception.cc:774
#5 0x0000000010000d74 in main () at exception_test.cpp:5
#6 0x0000000010000ae8 in _start (argc=1342447624, argv=0x50042060, env=0xffffffffffffcc30, obj=<value optimized out>, cleanup=<value optimized out>, ps_strings=<value optimized out>)
at /usr/src/lib/csu/powerpc64/crt1.c:94
#7 0x0000000050017b70 in .text () at /usr/src/libexec/rtld-elf/powerpc64/rtld_start.S:104
(gdb) print *context
$2 = {reg = 0xffffffffffffcc30, cfa = 0xffffffffffffd990, ra = 0x10000d78, lsda = 0x10000f74, bases = {tbase = 0x0, dbase = 0x0, func = 0x10000d30}, flags = 4611686018427387904, version = 0,
args_size = 0, by_value = 0xffffffffffffd108 ""}
(gdb) print dwarf_reg_size_table[3]
$3 = 8 '\b'
(gdb) print context->reg[3]
$4 = (void *) 0x0
And there is the problem: lack of the value
that is supposed to be available there: NULL
instead.
This traces back to. . .
# dwarfdump -v -v -F a.out
.eh_frame
fde:
< 0><0x100007a0:0x10000800><><cie offset 0x0000001c::cie index 0><fde offset 0x00000018 length: 0x00000014>
<eh aug data len 0x0>
0x100007a0: <off cfa=00(r1) >
fde section offset 24 0x00000018 cie offset for fde: 28 0x0000001c
0 DW_CFA_nop
1 DW_CFA_nop
2 DW_CFA_nop
3 DW_CFA_nop
4 DW_CFA_nop
5 DW_CFA_nop
6 DW_CFA_nop
< 1><0x10000d30:0x10000dac><main><cie offset 0x00000024::cie index 1><fde offset 0x00000068 length: 0x00000024>
<eh aug data len 0x8 bytes 0x00 00 00 00 00 00 00 1b >
0x10000d30: <off cfa=00(r1) >
0x10000d40: <off cfa=128(r1) > <off r31=-8(cfa) > <off r65=16(cfa) >
0x10000d44: <off cfa=128(r31) > <off r31=-8(cfa) > <off r65=16(cfa) >
fde section offset 104 0x00000068 cie offset for fde: 36 0x00000024
0 DW_CFA_advance_loc 16 (4 * 4)
1 DW_CFA_def_cfa_offset 128
4 DW_CFA_offset r31 -8 (1 * -8)
6 DW_CFA_offset_extended_sf r65 16 (-2 * -8)
9 DW_CFA_advance_loc 4 (1 * 4)
10 DW_CFA_def_cfa_register r31
12 DW_CFA_nop
13 DW_CFA_nop
14 DW_CFA_nop
< 2><0x10000e38:0x10000e90><><cie offset 0x00000034::cie index 0><fde offset 0x00000030 length: 0x00000014>
<eh aug data len 0x0>
0x10000e38: <off cfa=00(r1) >
0x10000e3c: <off cfa=00(r1) > <off r65=r12 >
0x10000e4c: <off cfa=00(r1) >
fde section offset 48 0x00000030 cie offset for fde: 52 0x00000034
0 DW_CFA_advance_loc 4 (1 * 4)
1 DW_CFA_register r65 = r12
4 DW_CFA_advance_loc 16 (4 * 4)
5 DW_CFA_restore_extended r65
cie:
< 0> version 1
cie section offset 0 0x00000000
augmentation zR
code_alignment_factor 4
data_alignment_factor -8
return_address_register 65
eh aug data len 0x1 bytes 0x1b
bytes of initial instructions 7
cie length 20
initial instructions
0 DW_CFA_def_cfa r1 0
3 DW_CFA_nop
4 DW_CFA_nop
5 DW_CFA_nop
6 DW_CFA_nop
< 1> version 1
cie section offset 72 0x00000048
augmentation zPLR
code_alignment_factor 4
data_alignment_factor -8
return_address_register 65
eh aug data len 0xb bytes 0x94 00 00 00 00 00 01 04 a5 14 1b
bytes of initial instructions 3
cie length 28
initial instructions
0 DW_CFA_def_cfa r1 0
Which is missing the DW_CFA_<?> material for the
scratch registers (such as the one tied to index 3
for the exceptionObject) so the context->reg[3]
value at run-time was junk (NULL) by not having
been filled in. Thus the code fails.
===
Mark Millard
markmi at dsl-only.net
More information about the freebsd-current
mailing list