Re: C++ in jemalloc

From: Mark Millard <markmi_at_dsl-only.net>
Date: Sat, 7 Oct 2017 02:18:37 -0700
[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
Received on Sat Oct 07 2017 - 07:18:41 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:41:13 UTC