<div dir="ltr">If mixing libunwind with other personality function like libgcc_s<div>First, we use <span style="color:rgb(0,0,0);font-family:monospace;white-space:pre">_US_VIRTUAL_UNWIND_FRAME | _US_FORCE_UNWIND in _Unwind_Backtrace() which calls continue_unwind(), so why not call _US_UNWIND_FRAME_RESUME? It calls continue_unwind() too. </span><a href="https://llvm.org/viewvc/llvm-project/libunwind/trunk/src/UnwindLevel1-gcc-ext.c?view=markup">https://llvm.org/viewvc/llvm-project/libunwind/trunk/src/UnwindLevel1-gcc-ext.c?view=markup</a></div><div>Second, _Unwind_Context is not compatible.<br><div>To make _Unwind_Context binary compatible in core registers with <span style="font-size:14px">phase1_vrs in libgcc_s, we should:</span></div><div><span style="font-size:14px">(1) Swap _registers and _addressSpace in UnwindCursor class.</span></div><div><span style="font-size:14px">(2) Make UnwindCursor aligned to 4 for ARM EHABI. </span></div><div><span style="font-size:14px"><b>I don't know why the first member of UnwindCursor align to 8 for ARM EHABI.  UnwindCursor implements the interface class AbstractUnwindCursor.</b></span></div><div><br></div><div><span style="font-size:14px">To conclude,</span></div><div><span style="font-size:14px">1. Mixing libunwind _Unwind_Backtrace with other personality function will lead to incompatible behavior. I suggest we call continue_unwinding() than call personality function.</span></div><div><span style="font-size:14px">2. Though we could change UnwindCursor to make it compatible with libgcc_s in some case and even  use </span><span style="color:rgb(0,0,0);font-family:monospace;white-space:pre">_US_UNWIND_FRAME_RESUME to make it compatible with gabi++</span><span style="font-size:14px">, it is not a good method.</span></div><div><span style="font-size:14px"><br></span></div><div><span style="font-size:14px">Regards,</span></div><div><span style="font-size:14px">Jean</span></div><div><br></div><div class="gmail_extra"><br><div class="gmail_quote">2018-02-27 23:06 GMT+08:00 Jean Lee <span dir="ltr"><<a href="mailto:xiaoyur347@gmail.com" target="_blank">xiaoyur347@gmail.com</a>></span>:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div>Background:</div>Android has an malloc debug function which described in <a href="https://android.googlesource.com/platform/bionic/+/master/libc/malloc_debug/" target="_blank">https://android.<wbr>googlesource.com/platform/<wbr>bionic/+/master/libc/malloc_<wbr>debug/</a>. When it is enabled, it use libunwind _Unwind_Backtrace to record malloc stacktrace and can analyze memory problems such as memory leaks.<div>Condition 1:<br><div>It works from Android 5.0 with libunwind(still in libcxxabi) commit <a href="https://llvm.org/viewvc/llvm-project?view=revision&revision=216730" target="_blank">https://llvm.org/<wbr>viewvc/llvm-project?view=<wbr>revision&revision=216730</a>.</div><div>This commit avoids call personality function likes __gxx_personality_v0 but with &__gxx_personality_v0 which means only in static build it can continue unwinding.</div></div><div><br></div><div>Condition 2:</div><div>Android 6.0 pick up libunwind(still in libcxxabi) commit <a href="https://llvm.org/viewvc/llvm-project?view=revision&revision=226822" target="_blank">https://llvm.org/<wbr>viewvc/llvm-project?view=<wbr>revision&revision=226822</a>.</div><div>This commit try to fix Condition 1 by call personality function in Generic Model.</div><div>And it leads to the problem I will describe later.</div><div><br></div><div>Condition 3:</div><div>Android 7.0 comes with libunwind move out from libcxxabi and pick up libunwind commit <a href="https://llvm.org/viewvc/llvm-project?view=revision&revision=238560" target="_blank">https://llvm.org/<wbr>viewvc/llvm-project?view=<wbr>revision&revision=238560</a>.</div><div>This commit do further more and only calls personality function in _Unwind_Backtrace. To use this commit, libcxxabi should pick up commit <a href="https://llvm.org/viewvc/llvm-project/libcxxabi/trunk/src/cxa_personality.cpp?r1=238561&r2=238560&pathrev=238561" target="_blank">https://llvm.org/<wbr>viewvc/llvm-project/libcxxabi/<wbr>trunk/src/cxa_personality.cpp?<wbr>r1=238561&r2=238560&pathrev=<wbr>238561</a>.</div><div><br></div><div>Problem in ARM EHABI likes armv7a:</div><div>When using malloc debug in Android, it means the application loads libc_malloc_debug first, and it is compiled with libunwind(llvm). And my application still use gnustl static or shared which means libgcc_s.a is used for user application.</div><div>And when the application calls malloc, it will go into libc_malloc_debug and call libunwind _Unwind_Backtrace() and _Unwind_Backtrace() will call personality function. In Android 6.0, it calls libgcc_s personality function in <a href="https://android.googlesource.com/toolchain/gcc/+/ndk-r15-release/gcc-4.9/libstdc++-v3/libsupc++/eh_personality.cc" target="_blank">https://android.<wbr>googlesource.com/toolchain/<wbr>gcc/+/ndk-r15-release/gcc-4.9/<wbr>libstdc++-v3/libsupc++/eh_<wbr>personality.cc</a>. And it dies with the backtrace as follows:</div><div><br></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div><div>02-25 21:42:28.269 F/DEBUG   (  285): pid: 12453, tid: 12453, name: mo.helloandroid  >>> com.jean.demo.helloandroid <<<</div></div><div><div>02-25 21:42:28.269 F/DEBUG   (  285): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0</div></div><div><div>02-25 21:42:28.289 F/DEBUG   (  285):     r0 00000001  r1 00004080  r2 00000000  r3 00000008</div></div><div><div>02-25 21:42:28.289 F/DEBUG   (  285):     r4 00004080  r5 bea56a28  r6 00000080  r7 00000000</div></div><div><div>02-25 21:42:28.289 F/DEBUG   (  285):     r8 bea564e4  r9 bea565a8  sl 80000000  fp 00000005</div></div><div><div>02-25 21:42:28.289 F/DEBUG   (  285):     ip b39c61b8  sp bea563b8  lr b39d6955  pc b39d64bc  cpsr 240d1c30</div></div><div><div>02-25 21:42:28.300 F/DEBUG   (  285):</div></div><div><div>02-25 21:42:28.300 F/DEBUG   (  285): backtrace:</div></div><div><div><br></div></div><div><div>02-25 21:42:28.300 F/DEBUG   (  285):     #00 pc 000144bc  /data/app/com.jean.demo.<wbr>helloandroid-1/lib/arm/<wbr>libnative-lib.so (_Unwind_VRS_Pop+47)</div></div><div><div>/Volumes/Android/buildbot/src/<wbr>android/gcc/toolchain/build/..<wbr>/gcc/gcc-4.9/libgcc/config/<wbr>arm/unwind-arm.c:240</div></div><div><div><br></div></div><div><div>02-25 21:42:28.300 F/DEBUG   (  285):     #01 pc 00014951  /data/app/com.jean.demo.<wbr>helloandroid-1/lib/arm/<wbr>libnative-lib.so (__gnu_unwind_execute+162)</div></div><div><div>/Volumes/Android/buildbot/src/<wbr>android/gcc/toolchain/build/..<wbr>/gcc/gcc-4.9/libgcc/config/<wbr>arm/pr-support.c:153</div></div><div><div><br></div></div><div><div>02-25 21:42:28.300 F/DEBUG   (  285):     #02 pc 00014b45  /data/app/com.jean.demo.<wbr>helloandroid-1/lib/arm/<wbr>libnative-lib.so (__gnu_unwind_frame+32)</div></div><div><div>/Volumes/Android/buildbot/src/<wbr>android/gcc/toolchain/build/..<wbr>/gcc/gcc-4.9/libgcc/config/<wbr>arm/pr-support.c:331</div></div><div><div><br></div></div><div><div>02-25 21:42:28.300 F/DEBUG   (  285):     #03 pc 00004599  /data/app/com.jean.demo.<wbr>helloandroid-1/lib/arm/<wbr>libnative-lib.so (__gxx_personality_v0+336)</div></div><div><div>/Volumes/Android/buildbot/src/<wbr>android/ndk-r15-release/<wbr>toolchain/gcc/gcc-4.9/libstdc+<wbr>+-v3/libsupc++/eh_personality.<wbr>cc:386</div></div><div><div><br></div></div><div><div>02-25 21:42:28.301 F/DEBUG   (  285):     #04 pc 00008517  /system/lib/libc_malloc_<wbr>debug_leak.so (_Unwind_Backtrace+130)</div></div><div><div>02-25 21:42:28.301 F/DEBUG   (  285):     #05 pc 00006003  /system/lib/libc_malloc_<wbr>debug_leak.so (get_backtrace(unsigned int*, unsigned int)+34)</div></div><div><div>02-25 21:42:28.301 F/DEBUG   (  285):     #06 pc 00006a7d  /system/lib/libc_malloc_<wbr>debug_leak.so (leak_malloc+84)</div></div><div><div>02-25 21:42:28.301 F/DEBUG   (  285):     #07 pc 00007911  /data/app/com.jean.demo.<wbr>helloandroid-1/lib/arm/<wbr>libnative-lib.so (operator new(unsigned int)+12)</div></div><div><div>02-25 21:42:28.301 F/DEBUG   (  285):     #08 pc 00006eb1  /data/app/com.jean.demo.<wbr>helloandroid-1/lib/arm/<wbr>libnative-lib.so (char* std::string::_S_construct<char const*>(char const*, char const*, std::allocator<char> const&, std::forward_iterator_tag)+<wbr>144)</div></div><div><div>02-25 21:42:28.302 F/DEBUG   (  285):     #09 pc 000071e3  /data/app/com.jean.demo.<wbr>helloandroid-1/lib/arm/<wbr>libnative-lib.so (std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&)+30)</div></div><div><div>02-25 21:42:28.302 F/DEBUG   (  285):     #10 pc 000041f3  /data/app/com.jean.demo.<wbr>helloandroid-1/lib/arm/<wbr>libnative-lib.so (Java_com_jean_demo_<wbr>helloandroid_MainActivity_<wbr>stringFromJNI+58)</div></div><div><div>02-25 21:42:28.302 F/DEBUG   (  285):     #11 pc 008629e9  /data/app/com.jean.demo.<wbr>helloandroid-1/oat/arm/base.<wbr>odex (offset 0x432000) (java.lang.String com.jean.demo.helloandroid.<wbr>MainActivity.stringFromJNI()+<wbr>76)</div></div><div><div>02-25 21:42:28.302 F/DEBUG   (  285):     #12 pc 008626f9  /data/app/com.jean.demo.<wbr>helloandroid-1/oat/arm/base.<wbr>odex (offset 0x432000) (void com.jean.demo.helloandroid.<wbr>MainActivity.onCreate(android.<wbr>os.Bundle)+444)</div></div></blockquote><div><br></div><div>After some investigate to this problem, I find there are some problems here.</div><div>(1) <b>Is it designed to mix libunwind(llvm) with libgcc_s personality routine?</b> libgcc_s has compatible _Unwind_Control_Block with libunwind but has incompatible _Unwind_Context with libunwind.</div><div>In gcc, _Unwind_Context is</div><div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">struct core_regs<br>{<br>  _uw r[16];<br>};<br>/* We use normal integer types here to avoid the compiler generating<br>   coprocessor instructions.  */<br>struct vfp_regs<br>{<br>  _uw64 d[16];<br>  _uw pad;<br>};<br>struct vfpv3_regs<br>{<br>  /* Always populated via VSTM, so no need for the "pad" field from<br>     vfp_regs (which is used to store the format word for FSTMX).  */<br>  _uw64 d[16];<br>};<br>struct wmmxd_regs<br>{<br>  _uw64 wd[16];<br>};<br>struct wmmxc_regs<br>{<br>  _uw wc[4];<br>};<br>typedef struct<br>{<br>  /* The first fields must be the same as a phase2_vrs.  */<br>  _uw demand_save_flags;<br>  struct core_regs core;<br>  _uw prev_sp; /* Only valid during forced unwinding.  */<br>  struct vfp_regs vfp;<br>  struct vfpv3_regs vfp_regs_16_to_31;<br>  struct wmmxd_regs wmmxd;<br>  struct wmmxc_regs wmmxc;<br>} phase1_vrs;</blockquote></div><div>But in libunwind, it is a class with vptr UnwindCursor<<wbr>LocalAddressSpace, Registers_arm>.</div><div><br></div><div>In <a href="https://android.googlesource.com/toolchain/gcc/+/ndk-r15-release/gcc-4.9/libgcc/config/arm/pr-support.c" target="_blank">https://android.<wbr>googlesource.com/toolchain/<wbr>gcc/+/ndk-r15-release/gcc-4.9/<wbr>libgcc/config/arm/pr-support.c</a><wbr>, it also calls</div><div>_Unwind_VRS_Set (context, _UVRSC_CORE, R_PC, _UVRSD_UINT32,</div><div><span class="gmail-m_-4295917725337934335gmail-Apple-tab-span" style="white-space:pre-wrap">                 </span>       &reg);</div><div>to store context but what's the context here?</div><div><br></div><div>(2) Since I have no way because Android use libunwind and our application should still use gnustl for a while. It means the mix will long exists.</div><div>(3) Actually in Condition 1, it sounds it does not call personality function for Generic Model, but since it calls _Unwind_VRS_Interpret, it really does as libcxxabi __gxx_personality_v0 does!</div><div>So, I have a question, <b>can we inline libcxxabi __gxx_personality_v0 in _Unwind_Backtrace</b> to avoid external call to personality function like libgcc_s and old libcxx+gabi++, and it mays dies in some condition.</div><div>If it can, actually we should only pick up __gnu_unwind_frame() for personality function.</div><div><br></div><div>Regards.</div></div>
</blockquote></div><br></div></div></div>