ndk icon indicating copy to clipboard operation
ndk copied to clipboard

Android backtraces don't work since gimli is used as the symbolizer

Open inferrna opened this issue 3 years ago • 9 comments

Got this non-informative backtrace in logcat:

12-16 22:26:30.581 12603 12619 I RustStdoutStderr: thread '<unnamed>' panicked at 'called 'Result::unwrap()' on an 'Err' value: GlutinCreationError(NoAvailablePixelFormat)', src/main.rs:74:71
12-16 22:26:30.581 12603 12619 I RustStdoutStderr: stack backtrace:
12-16 22:26:30.581 12603 12619 I RustStdoutStderr:    0: 0xdd581fee - <unknown>
12-16 22:26:30.581 12603 12619 I RustStdoutStderr:    1: 0xdd5966c6 - <unknown>
.....
12-16 22:26:30.584 12603 12619 I RustStdoutStderr:   25: 0xe957757e - <unknown>

Then, while trying

cargo apk gdb got this

Remote communication error.  Target disconnected.: Connection reset by peer.
(gdb) quit

Found in log

12-16 22:22:10.125 31207 31207 E adbd    : failed to connect to socket 'localfilesystem:/data/data/rust.conrod_android_skeleton/debug_socket': Connection refused
12-16 22:22:10.378 31207 31207 E adbd    : failed to connect to socket 'localfilesystem:/data/data/rust.conrod_android_skeleton/debug_socket': Connection refused

The app conrod_android_skeleton was set as "Debugging app" in settings (also same result was when it wasn't set). So, it obviously is a problem on my side. But I'd like to have an option for attaching all debug symbols right into binary.

inferrna avatar Dec 16 '20 14:12 inferrna

Hi, thanks for the report! Do you have a repository for testing it locally by chance?

msiglreith avatar Dec 16 '20 18:12 msiglreith

https://github.com/inferrna/conrod-android-skeleton

it's my tries to actualise this https://github.com/jbg/conrod-android-skeleton

inferrna avatar Dec 17 '20 13:12 inferrna

Hmm the missing backtrace symbolization seems to be a limitation of the backtrace library right now, but I will look a bit more around. Apparently, the rust compiler switched from libbacktrace to gimli this year and android support seems to be lacking right now: https://github.com/rust-lang/backtrace-rs/issues/351

msiglreith avatar Dec 20 '20 16:12 msiglreith

apparently there is support in backtrace-rs now. according to https://github.com/rust-lang/backtrace-rs/issues/442 some changes to the AndroidManifest.xml are required. those should probably be added in debug builds. however I still can't get it to work

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:tools="http://schemas.android.com/tools"
          package="com.myapp">

    <application
            tools:replace="android:extractNativeLibs"
            android:extractNativeLibs="true" />

</manifest>

dvc94ch avatar Dec 09 '21 16:12 dvc94ch

Just to mention that I'm seeing the same issue and also tried setting android:extractNativeLibs="true" as was mentioned as a workaround under https://github.com/rust-lang/backtrace-rs/issues/442 but that didn't seem to help.

I've tried with ndk 22b and 23b so far and I'm building for arm64-v8a.

As far as I could tell the library had debug symbols (checked with nm and readelf). I also double checked symbols weren't being stripped by extracting the library from the apk and checked that file had symbols.

rib avatar May 07 '22 03:05 rib

I'm not so sure now that backtrace-rs is really expected to support symbolizing a backtrace on Android (see https://github.com/rust-lang/backtrace-rs/issues/442#issuecomment-942396909) - I think it just tries to support getting the library offset for each stack frame.

Actually in my case I'm seeing that even the offsets aren't valid - they are far to large - even if I use the legacy apk packaging to ensure the shared libraries are separate files.

What I've realized I can do as a workaround though is to check for the backtrace that's automatically printed by Android itself because that at least has correct addresses / offsets. I then wrote a python script that just scrapes the offsets which can be piped to addr2line in the NDK:

#!/usr/bin/python3
import sys
import re

for line in sys.stdin:
    search = re.search('#[0-9]+ +pc +([0-9A-Fa-f]+) +', line)
    if search != None:
        print(search.group(1))

So then I can copy paste a backtrace into a file and get a backtrace with filenames, demangled functions and line numbers via:

cat backtrace.txt | py ./android-backtrace.py | 'path/to/toolchains/llvm/prebuilt/windows-x86_64/bin/aarch64-linux-android-addr2line.exe' -e ./app/src/main/jniLibs/arm64-v8a/libmain.so -f -C

A notable advantage of this approach is that it doesn't require packaged / uploaded libraries to have symbols (so long as you can reference a copy of the library with symbols when symbolizing) and doesn't require the use of extractNativeLibs.

For example with this backtrace from adb:
2022-05-10 04:54:22.928 29166-29166/? A/DEBUG:     #00 pc 0000000000021d94  /system/lib64/libc.so (abort+124)
2022-05-10 04:54:22.928 29166-29166/? A/DEBUG:     #01 pc 000000000199ad18  /data/app/co.realfit.agdkbevy-g7hRl_WmsH9ztNPfd-IkzA==/lib/arm64/libmain.so
2022-05-10 04:54:22.928 29166-29166/? A/DEBUG:     #02 pc 0000000001997b1c  /data/app/co.realfit.agdkbevy-g7hRl_WmsH9ztNPfd-IkzA==/lib/arm64/libmain.so
2022-05-10 04:54:22.928 29166-29166/? A/DEBUG:     #03 pc 00000000019979c0  /data/app/co.realfit.agdkbevy-g7hRl_WmsH9ztNPfd-IkzA==/lib/arm64/libmain.so
2022-05-10 04:54:22.928 29166-29166/? A/DEBUG:     #04 pc 00000000019976e8  /data/app/co.realfit.agdkbevy-g7hRl_WmsH9ztNPfd-IkzA==/lib/arm64/libmain.so
2022-05-10 04:54:22.928 29166-29166/? A/DEBUG:     #05 pc 0000000001995a88  /data/app/co.realfit.agdkbevy-g7hRl_WmsH9ztNPfd-IkzA==/lib/arm64/libmain.so
2022-05-10 04:54:22.928 29166-29166/? A/DEBUG:     #06 pc 0000000001997420  /data/app/co.realfit.agdkbevy-g7hRl_WmsH9ztNPfd-IkzA==/lib/arm64/libmain.so
2022-05-10 04:54:22.928 29166-29166/? A/DEBUG:     #07 pc 000000000014b604  /data/app/co.realfit.agdkbevy-g7hRl_WmsH9ztNPfd-IkzA==/lib/arm64/libmain.so
2022-05-10 04:54:22.928 29166-29166/? A/DEBUG:     #08 pc 000000000014b6a8  /data/app/co.realfit.agdkbevy-g7hRl_WmsH9ztNPfd-IkzA==/lib/arm64/libmain.so
2022-05-10 04:54:22.928 29166-29166/? A/DEBUG:     #09 pc 0000000000950224  /data/app/co.realfit.agdkbevy-g7hRl_WmsH9ztNPfd-IkzA==/lib/arm64/libmain.so
2022-05-10 04:54:22.928 29166-29166/? A/DEBUG:     #10 pc 0000000000b69ec0  /data/app/co.realfit.agdkbevy-g7hRl_WmsH9ztNPfd-IkzA==/lib/arm64/libmain.so
2022-05-10 04:54:22.928 29166-29166/? A/DEBUG:     #11 pc 0000000000a1f490  /data/app/co.realfit.agdkbevy-g7hRl_WmsH9ztNPfd-IkzA==/lib/arm64/libmain.so
2022-05-10 04:54:22.928 29166-29166/? A/DEBUG:     #12 pc 0000000000b64a24  /data/app/co.realfit.agdkbevy-g7hRl_WmsH9ztNPfd-IkzA==/lib/arm64/libmain.so
2022-05-10 04:54:22.928 29166-29166/? A/DEBUG:     #13 pc 0000000000b599f0  /data/app/co.realfit.agdkbevy-g7hRl_WmsH9ztNPfd-IkzA==/lib/arm64/libmain.so
2022-05-10 04:54:22.928 29166-29166/? A/DEBUG:     #14 pc 0000000000b594d8  /data/app/co.realfit.agdkbevy-g7hRl_WmsH9ztNPfd-IkzA==/lib/arm64/libmain.so
2022-05-10 04:54:22.928 29166-29166/? A/DEBUG:     #15 pc 0000000000b64774  /data/app/co.realfit.agdkbevy-g7hRl_WmsH9ztNPfd-IkzA==/lib/arm64/libmain.so
2022-05-10 04:54:22.928 29166-29166/? A/DEBUG:     #16 pc 000000000099f968  /data/app/co.realfit.agdkbevy-g7hRl_WmsH9ztNPfd-IkzA==/lib/arm64/libmain.so
2022-05-10 04:54:22.928 29166-29166/? A/DEBUG:     #17 pc 0000000001617d68  /data/app/co.realfit.agdkbevy-g7hRl_WmsH9ztNPfd-IkzA==/lib/arm64/libmain.so
2022-05-10 04:54:22.928 29166-29166/? A/DEBUG:     #18 pc 000000000014fa14  /data/app/co.realfit.agdkbevy-g7hRl_WmsH9ztNPfd-IkzA==/lib/arm64/libmain.so
2022-05-10 04:54:22.928 29166-29166/? A/DEBUG:     #19 pc 000000000014be74  /data/app/co.realfit.agdkbevy-g7hRl_WmsH9ztNPfd-IkzA==/lib/arm64/libmain.so (android_main+144)
2022-05-10 04:54:22.928 29166-29166/? A/DEBUG:     #20 pc 0000000001966740  /data/app/co.realfit.agdkbevy-g7hRl_WmsH9ztNPfd-IkzA==/lib/arm64/libmain.so (_rust_glue_entry+348)
2022-05-10 04:54:22.928 29166-29166/? A/DEBUG:     #21 pc 0000000001976654  /data/app/co.realfit.agdkbevy-g7hRl_WmsH9ztNPfd-IkzA==/lib/arm64/libmain.so
The above script will pull out:
0000000000021d94
000000000199ad18
0000000001997b1c
00000000019979c0
00000000019976e8
0000000001995a88
0000000001997420
000000000014b604
000000000014b6a8
0000000000950224
0000000000b69ec0
0000000000a1f490
0000000000b64a24
0000000000b599f0
0000000000b594d8
0000000000b64774
000000000099f968
0000000001617d68
000000000014fa14
000000000014be74
0000000001966740
0000000001976654
Which can be piped to addr2line to get:
??
??:0
std::sys::unix::abort_internal::hf2e00ab422f03a90
/rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c//library/std/src/sys/unix/mod.rs:259
rust_panic
/rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c//library/std/src/panicking.rs:748
std::panicking::rust_panic_with_hook::hcdc16bc1d6a90d9f
/rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c//library/std/src/panicking.rs:716
std::panicking::begin_panic_handler::_$u7b$$u7b$closure$u7d$$u7d$::h80c5bec89bedcc17
/rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c//library/std/src/panicking.rs:588
std::sys_common::backtrace::__rust_end_short_backtrace::hbdfac0e0f8306365
/rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c//library/std/src/sys_common/backtrace.rs:138
rust_begin_unwind
/rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c//library/std/src/panicking.rs:584
core::panicking::panic_fmt::h28a757e2227ef488
/rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c//library/core/src/panicking.rs:143
core::result::unwrap_failed::hc5bc744b126af212
/rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c//library/core/src/result.rs:1749
core::result::Result$LT$T$C$E$GT$::unwrap::hdee8c853a0eb3fec
/rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c/library/core/src/result.rs:1065
bevy_render::renderer::initialize_renderer::_$u7b$$u7b$closure$u7d$$u7d$::h0cd0ec9c415b7d46
C:\Users\Robert\src\bevy\crates\bevy_render\src\renderer/mod.rs:224
_$LT$core..future..from_generator..GenFuture$LT$T$GT$$u20$as$u20$core..future..future..Future$GT$::poll::hceb4b9af4b98638b
/rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c/library/core/src/future/mod.rs:84
futures_lite::future::block_on::_$u7b$$u7b$closure$u7d$$u7d$::hcea9b5092dbbef10
C:\Users\Robert\.cargo\registry\src\github.com-1ecc6299db9ec823\futures-lite-1.12.0\src/future.rs:89
std::thread::local::LocalKey$LT$T$GT$::try_with::h5f1204b6f3f53c68
/rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c/library/std/src/thread/local.rs:413
std::thread::local::LocalKey$LT$T$GT$::with::hce01bea0642e5b3f
/rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c/library/std/src/thread/local.rs:389
futures_lite::future::block_on::hb3d920eab81bb4be
C:\Users\Robert\.cargo\registry\src\github.com-1ecc6299db9ec823\futures-lite-1.12.0\src/future.rs:79
_$LT$bevy_render..RenderPlugin$u20$as$u20$bevy_app..plugin..Plugin$GT$::build::h6259e21f62b5446d
C:\Users\Robert\src\bevy\crates\bevy_render\src/lib.rs:140
bevy_app::plugin_group::PluginGroupBuilder::finish::hc623480a2b4343d0
C:\Users\Robert\src\bevy\crates\bevy_app\src/plugin_group.rs:112
bevy_app::app::App::add_plugins::h860e64c350394fbd
C:\Users\Robert\src\bevy\crates\bevy_app\src/app.rs:799
android_main
C:\Users\Robert\src\agdk-rust\examples\agdk-bevy/src/lib.rs:38
_rust_glue_entry
C:\Users\Robert\src\agdk-rust\game-activity\src/lib.rs:735
android_app_entry
C:\Users\Robert\src\agdk-rust\game-activity/csrc/game-activity/native_app_glue/android_native_app_glue.c:208

rib avatar May 10 '22 04:05 rib

Interesting how you managed to symbolize backtraces from logcat crash reports. I think that getting rust backtraces is a different issue. Many years ago before gimli became the default, backtraces did work, and they should work again.

dvc94ch avatar May 10 '22 11:05 dvc94ch

Yeah, at the very least it would be good if backtrace-rs could determine valid library offsets - ideally without requiring legacy apk packing. I guess I could live without the on-device symbolizing considering the implicit need to package libraries with symbols which in turn makes packaging and uploading slower for testing.

Presumably for some versions of Android it can work with the extractNativeLibs workaround, or else maybe there has been a regression somewhere in backtrace-rs / gimli because for all the backtraces i've seen people posting for Android issues they all look to have bogus offsets.

Maybe a small thing but I think it's more awkward to scrape the system-provided backtrace from adb than it would be to scrape a Rust backtrace in situations where you're filtering the adb log for a single process (just because the system backtrace gets dumped by another system process).

rib avatar May 10 '22 15:05 rib

Is there any solution?

AuTsing avatar Sep 17 '22 01:09 AuTsing