dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.16k stars 4.72k forks source link

[Android] Package libmonosgen-2.0.so with debug symbols in the runtime pack #77161

Open grendello opened 2 years ago

grendello commented 2 years ago

I am currently working on native debugging (with lldb) and native profiling (with simpleperf) for Xamarin.Android and I am facing the need to put an unstripped version of libmonosgen-2.0.so into the application APK.

Currently, libmonosgen-2.0.so is distributed stripped and the debug symbols are available from the debug symbol servers, to be downloaded with the dotnet-sybmol utility. This poses a problem for us, since we don't want to install anything on the end user's machine, thus we would need to (somehow) retrieve said symbols from the server without dotnet-symbol which is possible, but would require using some form of "internal" implementation detail (in the shape of URLs, signatures, IDs etc) that dotnet-sybmol uses and that can potentially change without us noticing it.

Another issue we're facing is that Android doesn't appear to consider the .gnu_debuglink section when looking for debug info in a shared library, so we'd need to combine the retrieved debug information back in to libmonosgen-2.0.so. This is doable, but it would require us to distribute an external utility like eu-unstrip from the elfutils package, which we'd prefer to avoid.

The ideal solution for us would be if the runtime package contained an unstripped version of libmonosgen-2.0.so which we'd strip ourselves for builds that do not require the debug information and keep the debug info for debugging and profiling builds. I realize that it would somewhat increase the distribution size, but debug information usually compresses quite well in ZIP (quick tests show up to 70% of size decrease) and it may be decreased even more by using the DWARF5 debug format (by passing -gdwarf-5 flag to the compiler and linker) which on its own decreases the debug info size by around 30%.

It would also be great if the runtime were built with the -glldb flag passed to the compiler and linker, since that optimizes debug information for lldb - the only debugger shipped with the Android NDK.

ghost commented 2 years ago

Tagging subscribers to this area: @tommcdon See info in area-owners.md if you want to be subscribed.

Issue Details
I am currently working on native debugging (with `lldb`) and native profiling (with [`simpleperf`](https://android.googlesource.com/platform/system/extras/+/master/simpleperf/doc/README.md)) for [Xamarin.Android](https://google.com/xamarin/xamarin-android/) and I am facing the need to put an unstripped version of `libmonosgen-2.0.so` into the application APK. Currently, `libmonosgen-2.0.so` is distributed stripped and the debug symbols are available from the debug symbol servers, to be downloaded with the `dotnet-sybmol` utility. This poses a problem for us, since we don't want to install anything on the end user's machine, thus we would need to (somehow) retrieve said symbols from the server without `dotnet-symbol` which is possible, but would require using some form of "internal" implementation detail (in the shape of URLs, signatures, IDs etc) that `dotnet-sybmol` uses and that can potentially change without us noticing it. Another issue we're facing is that Android doesn't appear to consider the `.gnu_debuglink` section when looking for debug info in a shared library, so we'd need to combine the retrieved debug information back in to `libmonosgen-2.0.so`. This is doable, but it would require us to distribute an external utility like `eu-unstrip` from the `elfutils` package, which we'd prefer to avoid. The ideal solution for us would be if the runtime package contained an unstripped version of `libmonosgen-2.0.so` which we'd strip ourselves for builds that do not require the debug information and keep the debug info for debugging and profiling builds. I realize that it would somewhat increase the distribution size, but debug information usually compresses quite well in ZIP (quick tests show up to 70% of size decrease) and it may be decreased even more by using the [DWARF5](https://dwarfstd.org/Dwarf5Std.php) debug format (by passing `-gdwarf-5` flag to the compiler and linker) which on its own decreases the debug info size by around 30%. It would also be great if the runtime were built with the `-glldb` flag passed to the compiler and linker, since that optimizes debug information for `lldb` - the only debugger shipped with the Android NDK.
Author: grendello
Assignees: -
Labels: `area-Diagnostics-coreclr`
Milestone: -
ghost commented 2 years ago

Tagging subscribers to 'arch-android': @steveisok, @akoeplinger See info in area-owners.md if you want to be subscribed.

Issue Details
I am currently working on native debugging (with `lldb`) and native profiling (with [`simpleperf`](https://android.googlesource.com/platform/system/extras/+/master/simpleperf/doc/README.md)) for [Xamarin.Android](https://google.com/xamarin/xamarin-android/) and I am facing the need to put an unstripped version of `libmonosgen-2.0.so` into the application APK. Currently, `libmonosgen-2.0.so` is distributed stripped and the debug symbols are available from the debug symbol servers, to be downloaded with the `dotnet-sybmol` utility. This poses a problem for us, since we don't want to install anything on the end user's machine, thus we would need to (somehow) retrieve said symbols from the server without `dotnet-symbol` which is possible, but would require using some form of "internal" implementation detail (in the shape of URLs, signatures, IDs etc) that `dotnet-sybmol` uses and that can potentially change without us noticing it. Another issue we're facing is that Android doesn't appear to consider the `.gnu_debuglink` section when looking for debug info in a shared library, so we'd need to combine the retrieved debug information back in to `libmonosgen-2.0.so`. This is doable, but it would require us to distribute an external utility like `eu-unstrip` from the `elfutils` package, which we'd prefer to avoid. The ideal solution for us would be if the runtime package contained an unstripped version of `libmonosgen-2.0.so` which we'd strip ourselves for builds that do not require the debug information and keep the debug info for debugging and profiling builds. I realize that it would somewhat increase the distribution size, but debug information usually compresses quite well in ZIP (quick tests show up to 70% of size decrease) and it may be decreased even more by using the [DWARF5](https://dwarfstd.org/Dwarf5Std.php) debug format (by passing `-gdwarf-5` flag to the compiler and linker) which on its own decreases the debug info size by around 30%. It would also be great if the runtime were built with the `-glldb` flag passed to the compiler and linker, since that optimizes debug information for `lldb` - the only debugger shipped with the Android NDK.
Author: grendello
Assignees: -
Labels: `os-android`, `area-Build-mono`
Milestone: -
srxqds commented 2 years ago

we also want to know how to debug with dbg with android studio, I have rename .dbg to .so said from https://github.com/dotnet/runtime/blob/main/docs/workflow/debugging/mono/android-debugging.md

image

grendello commented 2 years ago

Renaming the .dbg file to .so won't work alone. The "main" shared library (e.g. libmonosgen-2.0.so) has a special section named .gnu_debuglink which contains the name of the debug information file:

$ llvm-objdump -s --section=".gnu_debuglink" libmonosgen-2.0.so 

libmonosgen-2.0.so: file format elf64-littleaarch64
Contents of section .gnu_debuglink:
 0000 6c69626d 6f6e6f73 67656e2d 322e302e  libmonosgen-2.0.
 0010 736f2e64 62670000 0b3a6766           so.dbg...:gf

You can see here that it expects to find a file name libmonosgen-2.0.so.dbg, in the same directory. So if you wanted it to find the renamed debug info file, you'd have to do the following:

$ llvm-objcopy --remove-section=.gnu_debuglink libmonosgen-2.0.so
$ mv libmonosgen-2.0.so.dbg libmonosgen-2.0-debug.so
$ llvm-objcopy --add-gnu-debuglink=libmonosgen-2.0-debug.so libmonosgen-2.0.so
#
# Now the new file is referenced
#
$ $ llvm-objdump -s --section=".gnu_debuglink" libmonosgen-2.0.so 

libmonosgen-2.0.so: file format elf64-littleaarch64
Contents of section .gnu_debuglink:
 0000 6c69626d 6f6e6f73 67656e2d 322e302d  libmonosgen-2.0-
 0010 64656275 672e736f 00000000 0b3a6766  debug.so.....:gf 

However, I tested this and I couldn't get Android to show detailed symbol information in the native stack traces. Debugging might work, however, didn't test that.

srxqds commented 2 years ago

i have tried use so.dbg and still not work

image

and also set symbol directories: image

set source map in LLDB Startup Commands

settings set target.source-map /home/unrealmono/netease-gitlab/dotnet/runtime E:\work\netease-gitlab\dotnet\runtime

srxqds commented 2 years ago

so can you have tried debug with android studio success?

srxqds commented 2 years ago

I have tried with two steps settings make work:

  1. Run>Edit Configurations>Debugger>Symbol Directories
  2. add runtime souce code into project files