Hi, I was trying to debug tailscale android app, which uses gomobile to build a native library.
I modified gradle and makefile (https://github.com/Pawloland/tailscale-android) trying to enable debugging, but still no dice and I think it is a problem with a gomobile command.
Following the instructions from https://wudev.digitaltorque.com/articles/go-mobile-debugging/ (a little outdated and for lldb-server, but found nothing better in gomobile docs), I run the debuggable tailscale app on device and try to attach delve debugger (built by termux team for android aarch64/arm64-v8a) as a tailscale app user on the android device, which gives me:
Warning: no debug info found, some functionality will be missing such as stack traces and variable evaluation. could not attach to pid 15448: could not read debug info (decoding dwarf section info at offset 0x0: too short) and could not read go symbol table (could not read section .gopclntab)
I already made sure that gradle isn't stripping debug sections from so files before creating apk, by extracting the same so file from .aar and apk - they are identical, have the same hash, so what is running on the android device is exactly what was produced by the gomobile command.
$ file jni/arm64-v8a/libgojni.so
jni/arm64-v8a/libgojni.so: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, Go BuildID=Ts5ArEYyGbhwiWuu0_PE/wFxCHtravb2Ar8LWYLZ8/te1zsP5PJWhXAjsQEQzc/tcjwJ7dW5tkyX7MCr4pd, BuildID[sha1]=e903f4c344ff0cef8fb1c9b543dde01a92ee5249, with debug_info, not stripped
$ readelf -S jni/arm64-v8a/libgojni.so
There are 45 section headers, starting at offset 0x21fff38:
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[ 0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] .note.androi[...] NOTE 0000000000000238 00000238
0000000000000098 0000000000000000 A 0 0 4
[ 2] .note.go.buildid NOTE 00000000000002d0 000002d0
0000000000000064 0000000000000000 A 0 0 4
[ 3] .note.gnu.bu[...] NOTE 0000000000000334 00000334
0000000000000024 0000000000000000 A 0 0 4
[ 4] .dynsym DYNSYM 0000000000000358 00000358
0000000000003618 0000000000000018 A 8 1 8
[ 5] .gnu.version VERSYM 0000000000003970 00003970
0000000000000482 0000000000000002 A 4 0 2
[ 6] .gnu.version_r VERNEED 0000000000003df4 00003df4
0000000000000040 0000000000000000 A 8 2 4
[ 7] .gnu.hash GNU_HASH 0000000000003e38 00003e38
0000000000000e28 0000000000000000 A 4 0 8
[ 8] .dynstr STRTAB 0000000000004c60 00004c60
0000000000006530 0000000000000000 A 0 0 1
[ 9] .rela.dyn RELA 000000000000b190 0000b190
00000000002ade60 0000000000000018 A 4 0 8
[10] .rela.plt RELA 00000000002b8ff0 002b8ff0
0000000000000570 0000000000000018 AI 4 21 8
[11] .rodata PROGBITS 00000000002b9560 002b9560
0000000000109180 0000000000000000 AMS 0 0 32
[12] .eh_frame_hdr PROGBITS 00000000003c26e0 003c26e0
0000000000000c34 0000000000000000 A 0 0 4
[13] .eh_frame PROGBITS 00000000003c3318 003c3318
00000000000045a0 0000000000000000 A 0 0 8
[14] .text PROGBITS 00000000003c78c0 003c78c0
0000000000ceaed8 0000000000000000 AX 0 0 16
[15] .plt PROGBITS 00000000010b27a0 010b27a0
00000000000003c0 0000000000000000 AX 0 0 16
[16] .data.rel.ro PROGBITS 00000000010b6b60 010b2b60
000000000092cb10 0000000000000000 WA 0 0 32
[17] .fini_array FINI_ARRAY 00000000019e3670 019df670
0000000000000010 0000000000000000 WA 0 0 8
[18] .init_array INIT_ARRAY 00000000019e3680 019df680
0000000000000008 0000000000000000 WA 0 0 8
[19] .dynamic DYNAMIC 00000000019e3688 019df688
00000000000001b0 0000000000000010 WA 8 0 8
[20] .got PROGBITS 00000000019e3838 019df838
0000000000000438 0000000000000000 WA 0 0 8
[21] .got.plt PROGBITS 00000000019e3c70 019dfc70
00000000000001e8 0000000000000000 WA 0 0 8
[22] .relro_padding NOBITS 00000000019e3e58 019dfe58
00000000000001a8 0000000000000000 WA 0 0 1
[23] .go.buildinfo PROGBITS 00000000019e7e60 019dfe60
0000000000001150 0000000000000000 WA 0 0 16
[24] .go.fipsinfo PROGBITS 00000000019e8fc0 019e0fc0
0000000000000078 0000000000000000 WA 0 0 32
[25] .noptrdata PROGBITS 00000000019e9040 019e1040
000000000006e5a1 0000000000000000 WA 0 0 32
[26] .data PROGBITS 0000000001a57600 01a4f600
0000000000023580 0000000000000000 WA 0 0 32
[27] .bss NOBITS 0000000001a7ab80 01a72b80
0000000000032be0 0000000000000000 WA 0 0 32
[28] .noptrbss NOBITS 0000000001aad760 01a72b80
0000000000025d40 0000000000000000 WA 0 0 32
[29] .comment PROGBITS 0000000000000000 01a72b80
000000000000014f 0000000000000001 MS 0 0 1
[30] .debug_abbrev PROGBITS 0000000000000000 01a72ccf
0000000000000b02 0000000000000000 C 0 0 1
[31] .debug_line PROGBITS 0000000000000000 01a737d1
00000000001189ae 0000000000000000 C 0 0 1
[32] .debug_frame PROGBITS 0000000000000000 01b8c17f
0000000000075fef 0000000000000000 C 0 0 1
[33] .debug_gdb_s[...] PROGBITS 0000000000000000 01c0216e
000000000000003f 0000000000000000 0 0 1
[34] .debug_info PROGBITS 0000000000000000 01c021ad
000000000025e39e 0000000000000000 C 0 0 1
[35] .debug_loclists PROGBITS 0000000000000000 01e6054b
000000000005483b 0000000000000000 C 0 0 1
[36] .debug_rnglists PROGBITS 0000000000000000 01eb4d86
000000000001e08c 0000000000000000 C 0 0 1
[37] .debug_addr PROGBITS 0000000000000000 01ed2e12
0000000000010661 0000000000000000 C 0 0 1
[38] .debug_loc PROGBITS 0000000000000000 01ee3473
000000000000472d 0000000000000000 C 0 0 1
[39] .debug_str PROGBITS 0000000000000000 01ee7ba0
0000000000002403 0000000000000001 MSC 0 0 1
[40] .debug_ranges PROGBITS 0000000000000000 01ee9fa3
00000000000000e7 0000000000000000 C 0 0 1
[41] .debug_aranges PROGBITS 0000000000000000 01eea08a
0000000000000030 0000000000000000 0 0 1
[42] .symtab SYMTAB 0000000000000000 01eea0c0
00000000000f96a8 0000000000000018 44 41991 8
[43] .shstrtab STRTAB 0000000000000000 01fe3768
00000000000001fc 0000000000000000 0 0 1
[44] .strtab STRTAB 0000000000000000 01fe3964
000000000021c5d1 0000000000000000 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
L (link order), O (extra OS processing required), G (group), T (TLS),
C (compressed), x (unknown), o (OS specific), E (exclude),
D (mbind), p (processor specific)
From the above I confirmed, that the .gopclntab section is really missing. I am not an expert on the whole compilation process, but I think, there is a problem with gomobile command removing sections used by dlv debugger, or not building them in?
ChatGPT tells me, that:
When Go uses external linking for c-shared, it always injects the following flags into the external linker call, even though -x does not print them cleanly as one line:
🔴 Implicit LLD flags
-Wl,--gc-sections
-Wl,--build-id
-Wl,--eh-frame-hdr
-shared
The killer is:
-Wl,--gc-sections
Why this is fatal to .gopclntab
- .gopclntab is not referenced by any relocation
- it is not SHF_ALLOC
- it exists only for the Go runtime / debugger
LLD sees it as:
“dead data → safe to delete”
So it is garbage-collected by the linker, not stripped.
That’s why:
- .debug_info survives (special-cased)
- .gopclntab disappears
There is no flag you can pass via:
- -ldflags
- -extldflags
- gomobile
to disable it.
Go does not expose a way to say:
-Wl,--no-gc-sections
for c-shared.
I write here in case someone can help me, because I am stuck and don't trust AI is correct on it.
If someone has some tutorial or documentation regarding real time debugging go native lib in android studio it would be very helpful.
Hi, I was trying to debug tailscale android app, which uses gomobile to build a native library.
I modified gradle and makefile (https://github.com/Pawloland/tailscale-android) trying to enable debugging, but still no dice and I think it is a problem with a gomobile command.
Following the instructions from https://wudev.digitaltorque.com/articles/go-mobile-debugging/ (a little outdated and for lldb-server, but found nothing better in gomobile docs), I run the debuggable tailscale app on device and try to attach delve debugger (built by termux team for android aarch64/arm64-v8a) as a tailscale app user on the android device, which gives me:
Warning: no debug info found, some functionality will be missing such as stack traces and variable evaluation. could not attach to pid 15448: could not read debug info (decoding dwarf section info at offset 0x0: too short) and could not read go symbol table (could not read section .gopclntab)
I already made sure that gradle isn't stripping debug sections from so files before creating apk, by extracting the same so file from .aar and apk - they are identical, have the same hash, so what is running on the android device is exactly what was produced by the gomobile command.
$ file jni/arm64-v8a/libgojni.so jni/arm64-v8a/libgojni.so: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, Go BuildID=Ts5ArEYyGbhwiWuu0_PE/wFxCHtravb2Ar8LWYLZ8/te1zsP5PJWhXAjsQEQzc/tcjwJ7dW5tkyX7MCr4pd, BuildID[sha1]=e903f4c344ff0cef8fb1c9b543dde01a92ee5249, with debug_info, not stripped $ readelf -S jni/arm64-v8a/libgojni.so There are 45 section headers, starting at offset 0x21fff38: Section Headers: [Nr] Name Type Address Offset Size EntSize Flags Link Info Align [ 0] NULL 0000000000000000 00000000 0000000000000000 0000000000000000 0 0 0 [ 1] .note.androi[...] NOTE 0000000000000238 00000238 0000000000000098 0000000000000000 A 0 0 4 [ 2] .note.go.buildid NOTE 00000000000002d0 000002d0 0000000000000064 0000000000000000 A 0 0 4 [ 3] .note.gnu.bu[...] NOTE 0000000000000334 00000334 0000000000000024 0000000000000000 A 0 0 4 [ 4] .dynsym DYNSYM 0000000000000358 00000358 0000000000003618 0000000000000018 A 8 1 8 [ 5] .gnu.version VERSYM 0000000000003970 00003970 0000000000000482 0000000000000002 A 4 0 2 [ 6] .gnu.version_r VERNEED 0000000000003df4 00003df4 0000000000000040 0000000000000000 A 8 2 4 [ 7] .gnu.hash GNU_HASH 0000000000003e38 00003e38 0000000000000e28 0000000000000000 A 4 0 8 [ 8] .dynstr STRTAB 0000000000004c60 00004c60 0000000000006530 0000000000000000 A 0 0 1 [ 9] .rela.dyn RELA 000000000000b190 0000b190 00000000002ade60 0000000000000018 A 4 0 8 [10] .rela.plt RELA 00000000002b8ff0 002b8ff0 0000000000000570 0000000000000018 AI 4 21 8 [11] .rodata PROGBITS 00000000002b9560 002b9560 0000000000109180 0000000000000000 AMS 0 0 32 [12] .eh_frame_hdr PROGBITS 00000000003c26e0 003c26e0 0000000000000c34 0000000000000000 A 0 0 4 [13] .eh_frame PROGBITS 00000000003c3318 003c3318 00000000000045a0 0000000000000000 A 0 0 8 [14] .text PROGBITS 00000000003c78c0 003c78c0 0000000000ceaed8 0000000000000000 AX 0 0 16 [15] .plt PROGBITS 00000000010b27a0 010b27a0 00000000000003c0 0000000000000000 AX 0 0 16 [16] .data.rel.ro PROGBITS 00000000010b6b60 010b2b60 000000000092cb10 0000000000000000 WA 0 0 32 [17] .fini_array FINI_ARRAY 00000000019e3670 019df670 0000000000000010 0000000000000000 WA 0 0 8 [18] .init_array INIT_ARRAY 00000000019e3680 019df680 0000000000000008 0000000000000000 WA 0 0 8 [19] .dynamic DYNAMIC 00000000019e3688 019df688 00000000000001b0 0000000000000010 WA 8 0 8 [20] .got PROGBITS 00000000019e3838 019df838 0000000000000438 0000000000000000 WA 0 0 8 [21] .got.plt PROGBITS 00000000019e3c70 019dfc70 00000000000001e8 0000000000000000 WA 0 0 8 [22] .relro_padding NOBITS 00000000019e3e58 019dfe58 00000000000001a8 0000000000000000 WA 0 0 1 [23] .go.buildinfo PROGBITS 00000000019e7e60 019dfe60 0000000000001150 0000000000000000 WA 0 0 16 [24] .go.fipsinfo PROGBITS 00000000019e8fc0 019e0fc0 0000000000000078 0000000000000000 WA 0 0 32 [25] .noptrdata PROGBITS 00000000019e9040 019e1040 000000000006e5a1 0000000000000000 WA 0 0 32 [26] .data PROGBITS 0000000001a57600 01a4f600 0000000000023580 0000000000000000 WA 0 0 32 [27] .bss NOBITS 0000000001a7ab80 01a72b80 0000000000032be0 0000000000000000 WA 0 0 32 [28] .noptrbss NOBITS 0000000001aad760 01a72b80 0000000000025d40 0000000000000000 WA 0 0 32 [29] .comment PROGBITS 0000000000000000 01a72b80 000000000000014f 0000000000000001 MS 0 0 1 [30] .debug_abbrev PROGBITS 0000000000000000 01a72ccf 0000000000000b02 0000000000000000 C 0 0 1 [31] .debug_line PROGBITS 0000000000000000 01a737d1 00000000001189ae 0000000000000000 C 0 0 1 [32] .debug_frame PROGBITS 0000000000000000 01b8c17f 0000000000075fef 0000000000000000 C 0 0 1 [33] .debug_gdb_s[...] PROGBITS 0000000000000000 01c0216e 000000000000003f 0000000000000000 0 0 1 [34] .debug_info PROGBITS 0000000000000000 01c021ad 000000000025e39e 0000000000000000 C 0 0 1 [35] .debug_loclists PROGBITS 0000000000000000 01e6054b 000000000005483b 0000000000000000 C 0 0 1 [36] .debug_rnglists PROGBITS 0000000000000000 01eb4d86 000000000001e08c 0000000000000000 C 0 0 1 [37] .debug_addr PROGBITS 0000000000000000 01ed2e12 0000000000010661 0000000000000000 C 0 0 1 [38] .debug_loc PROGBITS 0000000000000000 01ee3473 000000000000472d 0000000000000000 C 0 0 1 [39] .debug_str PROGBITS 0000000000000000 01ee7ba0 0000000000002403 0000000000000001 MSC 0 0 1 [40] .debug_ranges PROGBITS 0000000000000000 01ee9fa3 00000000000000e7 0000000000000000 C 0 0 1 [41] .debug_aranges PROGBITS 0000000000000000 01eea08a 0000000000000030 0000000000000000 0 0 1 [42] .symtab SYMTAB 0000000000000000 01eea0c0 00000000000f96a8 0000000000000018 44 41991 8 [43] .shstrtab STRTAB 0000000000000000 01fe3768 00000000000001fc 0000000000000000 0 0 1 [44] .strtab STRTAB 0000000000000000 01fe3964 000000000021c5d1 0000000000000000 0 0 1 Key to Flags: W (write), A (alloc), X (execute), M (merge), S (strings), I (info), L (link order), O (extra OS processing required), G (group), T (TLS), C (compressed), x (unknown), o (OS specific), E (exclude), D (mbind), p (processor specific)From the above I confirmed, that the .gopclntab section is really missing. I am not an expert on the whole compilation process, but I think, there is a problem with gomobile command removing sections used by dlv debugger, or not building them in?
ChatGPT tells me, that:
I write here in case someone can help me, because I am stuck and don't trust AI is correct on it.
If someone has some tutorial or documentation regarding real time debugging go native lib in android studio it would be very helpful.