Skip to content

cmd/link,x/mobile: Generated .aar files have .so that miss .gopclntab section which prevents dlv debugger from working #77484

Description

@Pawloland

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    DebuggingNeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.compiler/runtimeIssues related to the Go compiler and/or runtime.mobileAndroid, iOS, and x/mobile

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    Status
    Todo

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions