On Thu, 21 May 2026 06:42:00 GMT, Yasumasa Suenaga <[email protected]> wrote:
> `jhsdb jstack --mixed` would try to unwind all of native call frames. It will > reach `_start()` (startup routine by glibc), but it couldn't on the JDK built > by older glibc such as glibc-2.12 (used in devkit for Linux x86_64). > > Expected: > > 0x000055ad324dfadb main + 0x13b > 0x00007f3df876c681 __libc_start_call_main + 0x81 > 0x00007f3df876c798 __libc_start_main_alias_2 + 0x88 > 0x000055ad324dfb79 _start + 0x25 > > > Actual (no `_start` in call stacks): > > 0x000055ad324dfadb main + 0x13b > 0x00007f3df876c681 __libc_start_call_main + 0x81 > 0x00007f3df876c798 __libc_start_main_alias_2 + 0x88 > > > Startup routine would be provided by crt1.o, and it would be linked into > `java`. `_start()` in crt1.o by glibc-2.12 does not have Frame Description > Entry (FDE) in DWARF. In DWARF parser in SA assumes native function has FDE, > thus unwinder in SA would stop if it cannot find appropriate DWARF > information. > > I saw the problem on `_start()` only so far. This is not critical, but same > problem can happen on other places (functions / libraries). We cannot find > caller frame from DWARF-less function of course, but we should show the frame > even if it does not have DWARF. > > --------- > - [x] I confirm that I make this contribution in accordance with the [OpenJDK > Interim AI Policy](https://openjdk.org/legal/ai). I think this is good, just wanted to mention that with the change I see (on x64) before main it does find a new frame, but no symbol: ----------------- 844607 ----------------- 0x00007f512823938a __futex_abstimed_wait_common + 0xca 0x00007f512823de34 __pthread_clockjoin_ex + 0x144 0x00007f51283cdd16 CallJavaMainInNewThread + 0xa6 0x00007f51283cadae ContinueInNewThread + 0x6e 0x00007f51283cbafc JLI_Launch + 0xb4c 0x000055fbde081ad4 main + 0x134 0x00007f51281db610 __libc_start_call_main + 0x80 0x00007f51281db6c0 __libc_start_main_alias_2 + 0x80 0x000055fbde081b71 ???????? And that last ??? frame is in _start, if I look in gdb: ... 0x000055fbde081b57 <_start+15>: lea 0x112(%rip),%r8 # 0x55fbde081c70 <__libc_csu_fini> 0x000055fbde081b5e <_start+22>: lea 0x11b(%rip),%rcx # 0x55fbde081c80 <__libc_csu_init> 0x000055fbde081b65 <_start+29>: lea -0x1cc(%rip),%rdi # 0x55fbde0819a0 <main> 0x000055fbde081b6c <_start+36>: call 0x55fbde0818e0 <__libc_start_main@plt> 0x000055fbde081b71 <_start+41>: hlt ... ..so, it's right to include it, there is code there, in the java binary. Seeing what happens before main() is not a critical task for the JVM tools, we might say it's out of scope and we should be using a native debugger. There may be other examples in odd libraries or JVM internals that could use this, so yes maybe we would rather have the ??? than terminate. readelf says _start is the last item in the bin/java symtab: Symbol table '.symtab' contains 45 entries: Num: Value Size Type Bind Vis Ndx Name 44: 0000000000000b48 0 FUNC GLOBAL DEFAULT 13 _start But it's size is zero. There is no range we can match. We have had that conversation before somewhere about matching a symbol on a specific match without needing a range, but we are not at the first byte of _start, so that's no help. We probably are stuck for now with ???s where _start has size zero, it does not seem worth major effort to find out the size of the actual code there. ------------- Marked as reviewed by kevinw (Reviewer). PR Review: https://git.openjdk.org/jdk/pull/31230#pullrequestreview-4808308485
