From 32d355992577941e18c0a29c2acb06c8e16a6f06 Mon Sep 17 00:00:00 2001 From: Yasumasa Suenaga Date: Tue, 19 May 2026 14:23:49 +0000 Subject: [PATCH] 8377690: serviceability/sa/TestJhsdbJstackMixedWithXComp.java tests failing Reviewed-by: cjplummer, kevinw --- .../linux/native/libsaproc/dwarf.cpp | 49 +++++++++++-------- .../linux/native/libsaproc/dwarf.hpp | 5 +- .../linux/aarch64/LinuxAARCH64CFrame.java | 4 +- .../linux/amd64/LinuxAMD64CFrame.java | 4 +- 4 files changed, 34 insertions(+), 28 deletions(-) diff --git a/src/jdk.hotspot.agent/linux/native/libsaproc/dwarf.cpp b/src/jdk.hotspot.agent/linux/native/libsaproc/dwarf.cpp index 28eb92a285f..22ddf8f167e 100644 --- a/src/jdk.hotspot.agent/linux/native/libsaproc/dwarf.cpp +++ b/src/jdk.hotspot.agent/linux/native/libsaproc/dwarf.cpp @@ -31,7 +31,8 @@ DwarfParser::DwarfParser(lib_info *lib) : _lib(lib), _buf(NULL), - _encoding(0), + _has_augmentation(false), + _fde_ptr_encoding(0), _code_factor(0), _data_factor(0), _current_pc(0L) { @@ -106,17 +107,23 @@ bool DwarfParser::process_cie(unsigned char *start_of_entry, uint32_t id) { _data_factor = static_cast(read_leb(true)); enum DWARF_Register initial_ra = static_cast(*_buf++); - if (strpbrk(augmentation_string, "LP") != NULL) { - // Language personality routine (P) and Language Specific Data Area (LSDA:L) - // are not supported because we need compliant Unwind Library Interface, - // but we want to unwind without it. - // - // Unwind Library Interface (SysV ABI AMD64 6.2) - // https://software.intel.com/sites/default/files/article/402129/mpx-linux64-abi.pdf - return false; - } else if (strchr(augmentation_string, 'R') != NULL) { - read_leb(false); // augmentation length - _encoding = *_buf++; + if (*augmentation_string == 'z') { + _has_augmentation = true; + read_leb(false); // Skip augmentation length + augmentation_string++; // Skip first char ('z') + while (*augmentation_string != '\0') { + if (*augmentation_string == 'R') { + _fde_ptr_encoding = *_buf++; + } else if (*augmentation_string == 'P') { + print_debug("DWARF Warning: Ignore augmentation: P\n"); + unsigned char enc = *_buf++; // first argument (encoding) + get_decoded_value(enc); // skip second argument (personality routine handler) + } else if (*augmentation_string == 'L') { + print_debug("DWARF Warning: Ignore augmentation: L\n"); + _buf++; // skip 1 arguments + } + augmentation_string++; + } } // Clear state @@ -147,7 +154,7 @@ void DwarfParser::parse_dwarf_instructions(uintptr_t begin, uintptr_t pc, const case 0x0: // DW_CFA_nop return; case 0x01: // DW_CFA_set_loc - operand1 = get_decoded_value(); + operand1 = get_decoded_value(_fde_ptr_encoding); if (_current_pc != 0L) { _current_pc = operand1; } @@ -239,11 +246,11 @@ void DwarfParser::parse_dwarf_instructions(uintptr_t begin, uintptr_t pc, const } /* from dwarf.c in binutils */ -uint32_t DwarfParser::get_decoded_value() { +uint32_t DwarfParser::get_decoded_value(unsigned char enc) { int size; uintptr_t result; - switch (_encoding & 0x7) { + switch (enc & 0x7) { case 0: // DW_EH_PE_absptr size = sizeof(void *); result = *(reinterpret_cast(_buf)); @@ -272,7 +279,7 @@ uint32_t DwarfParser::get_decoded_value() { size = 4; } else #endif - if ((_encoding & 0x70) == 0x10) { // 0x10 = DW_EH_PE_pcrel + if ((enc & 0x70) == 0x10) { // 0x10 = DW_EH_PE_pcrel result += _lib->eh_frame.v_addr + static_cast(_buf - _lib->eh_frame.data); } else if (size == 2) { result = static_cast(result) + _lib->eh_frame.v_addr + static_cast(_buf - _lib->eh_frame.data); @@ -287,7 +294,7 @@ unsigned int DwarfParser::get_pc_range() { int size; uintptr_t result; - switch (_encoding & 0x7) { + switch (_fde_ptr_encoding & 0x7) { case 0: // DW_EH_PE_absptr size = sizeof(void *); result = *(reinterpret_cast(_buf)); @@ -334,7 +341,7 @@ bool DwarfParser::process_dwarf(const uintptr_t pc) { uint32_t id = *(reinterpret_cast(_buf)); _buf += 4; if (id != 0) { // FDE - uintptr_t pc_begin = get_decoded_value() + _lib->eh_frame.library_base_addr; + uintptr_t pc_begin = get_decoded_value(_fde_ptr_encoding) + _lib->eh_frame.library_base_addr; uintptr_t pc_end = pc_begin + get_pc_range(); if ((pc >= pc_begin) && (pc < pc_end)) { @@ -344,8 +351,10 @@ bool DwarfParser::process_dwarf(const uintptr_t pc) { } // Skip Augumenation - uintptr_t augmentation_length = read_leb(false); - _buf += augmentation_length; // skip + if (_has_augmentation) { + uintptr_t augmentation_length = read_leb(false); + _buf += augmentation_length; + } // Process FDE parse_dwarf_instructions(pc_begin, pc, next_entry); diff --git a/src/jdk.hotspot.agent/linux/native/libsaproc/dwarf.hpp b/src/jdk.hotspot.agent/linux/native/libsaproc/dwarf.hpp index 2bfdba65a78..30d5ddaa50b 100644 --- a/src/jdk.hotspot.agent/linux/native/libsaproc/dwarf.hpp +++ b/src/jdk.hotspot.agent/linux/native/libsaproc/dwarf.hpp @@ -63,7 +63,8 @@ class DwarfParser { private: const lib_info *_lib; unsigned char *_buf; - unsigned char _encoding; + bool _has_augmentation; + unsigned char _fde_ptr_encoding; unsigned int _code_factor; int _data_factor; @@ -76,7 +77,7 @@ class DwarfParser { uint64_t get_entry_length(); bool process_cie(unsigned char *start_of_entry, uint32_t id); void parse_dwarf_instructions(uintptr_t begin, uintptr_t pc, const unsigned char *end); - uint32_t get_decoded_value(); + uint32_t get_decoded_value(unsigned char enc); unsigned int get_pc_range(); public: diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/aarch64/LinuxAARCH64CFrame.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/aarch64/LinuxAARCH64CFrame.java index 5e8995464e6..8e09502cc37 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/aarch64/LinuxAARCH64CFrame.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/aarch64/LinuxAARCH64CFrame.java @@ -184,9 +184,7 @@ public final class LinuxAARCH64CFrame extends DwarfCFrame { return new LinuxAARCH64CFrame(linuxDbg(), senderSP, senderFP, null, senderPC, senderDwarf); } - // DWARF processing should succeed when the frame is native - // but it might fail if Common Information Entry (CIE) has language - // personality routine and/or Language Specific Data Area (LSDA). + // We cannot unwind anymore without appropriate DWARF. return null; } } diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/amd64/LinuxAMD64CFrame.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/amd64/LinuxAMD64CFrame.java index e58e2facdd7..c7cba470a04 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/amd64/LinuxAMD64CFrame.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/amd64/LinuxAMD64CFrame.java @@ -107,9 +107,7 @@ public final class LinuxAMD64CFrame extends DwarfCFrame { senderDwarf = createDwarfParser(linuxDbg(), senderPC.addOffsetTo(-1)); fallback = true; } catch (DebuggerException _) { - // DWARF processing should succeed when the frame is native - // but it might fail if Common Information Entry (CIE) has language - // personality routine and/or Language Specific Data Area (LSDA). + // We cannot unwind anymore without appropriate DWARF. return null; } }