mirror of
https://github.com/openjdk/jdk.git
synced 2026-03-04 05:00:31 +00:00
8240956: SEGV in DwarfParser::process_dwarf after JDK-8234624
Reviewed-by: sspitsyn, kevinw
This commit is contained in:
parent
83f7ee14da
commit
67cf35ee22
@ -75,7 +75,6 @@ bool DwarfParser::process_cie(unsigned char *start_of_entry, uint32_t id) {
|
||||
|
||||
char *augmentation_string = reinterpret_cast<char *>(_buf);
|
||||
bool has_ehdata = (strcmp("eh", augmentation_string) == 0);
|
||||
bool fde_encoded = (strchr(augmentation_string, 'R') != NULL);
|
||||
_buf += strlen(augmentation_string) + 1; // includes '\0'
|
||||
if (has_ehdata) {
|
||||
_buf += sizeof(void *); // Skip EH data
|
||||
@ -85,8 +84,16 @@ bool DwarfParser::process_cie(unsigned char *start_of_entry, uint32_t id) {
|
||||
_data_factor = static_cast<int>(read_leb(true));
|
||||
_return_address_reg = static_cast<enum DWARF_Register>(*_buf++);
|
||||
|
||||
if (fde_encoded) {
|
||||
uintptr_t augmentation_length = read_leb(false);
|
||||
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++;
|
||||
}
|
||||
|
||||
@ -285,7 +292,8 @@ unsigned int DwarfParser::get_pc_range() {
|
||||
bool DwarfParser::process_dwarf(const uintptr_t pc) {
|
||||
// https://refspecs.linuxfoundation.org/LSB_3.0.0/LSB-PDA/LSB-PDA/ehframechpt.html
|
||||
_buf = _lib->eh_frame.data;
|
||||
while (true) {
|
||||
unsigned char *end = _lib->eh_frame.data + _lib->eh_frame.size;
|
||||
while (_buf <= end) {
|
||||
uint64_t length = get_entry_length();
|
||||
if (length == 0L) {
|
||||
return false;
|
||||
@ -310,12 +318,12 @@ bool DwarfParser::process_dwarf(const uintptr_t pc) {
|
||||
|
||||
// Process FDE
|
||||
parse_dwarf_instructions(pc_begin, pc, next_entry);
|
||||
break;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
_buf = next_entry;
|
||||
}
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -224,6 +224,7 @@ bool read_eh_frame(struct ps_prochandle* ph, lib_info* lib) {
|
||||
lib->eh_frame.library_base_addr = lib->base;
|
||||
lib->eh_frame.v_addr = sh->sh_addr;
|
||||
lib->eh_frame.data = read_section_data(lib->fd, &ehdr, sh);
|
||||
lib->eh_frame.size = sh->sh_size;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -39,6 +39,7 @@ typedef struct eh_frame_info {
|
||||
uintptr_t library_base_addr;
|
||||
uintptr_t v_addr;
|
||||
unsigned char* data;
|
||||
int size;
|
||||
} eh_frame_info;
|
||||
|
||||
// list of shared objects
|
||||
|
||||
@ -38,17 +38,20 @@ final public class LinuxAMD64CFrame extends BasicCFrame {
|
||||
DwarfParser dwarf = null;
|
||||
|
||||
if (libptr != null) { // Native frame
|
||||
dwarf = new DwarfParser(libptr);
|
||||
try {
|
||||
dwarf = new DwarfParser(libptr);
|
||||
dwarf.processDwarf(rip);
|
||||
cfa = ((dwarf.getCFARegister() == AMD64ThreadContext.RBP) &&
|
||||
!dwarf.isBPOffsetAvailable())
|
||||
? context.getRegisterAsAddress(AMD64ThreadContext.RBP)
|
||||
: context.getRegisterAsAddress(dwarf.getCFARegister())
|
||||
.addOffsetTo(dwarf.getCFAOffset());
|
||||
} catch (DebuggerException e) {
|
||||
// Bail out to Java frame case
|
||||
// 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).
|
||||
return new LinuxAMD64CFrame(dbg, cfa, rip, dwarf, true);
|
||||
}
|
||||
cfa = ((dwarf.getCFARegister() == AMD64ThreadContext.RBP) &&
|
||||
!dwarf.isBPOffsetAvailable())
|
||||
? context.getRegisterAsAddress(AMD64ThreadContext.RBP)
|
||||
: context.getRegisterAsAddress(dwarf.getCFARegister())
|
||||
.addOffsetTo(dwarf.getCFAOffset());
|
||||
}
|
||||
|
||||
return (cfa == null) ? null
|
||||
@ -56,11 +59,16 @@ final public class LinuxAMD64CFrame extends BasicCFrame {
|
||||
}
|
||||
|
||||
private LinuxAMD64CFrame(LinuxDebugger dbg, Address cfa, Address rip, DwarfParser dwarf) {
|
||||
this(dbg, cfa, rip, dwarf, false);
|
||||
}
|
||||
|
||||
private LinuxAMD64CFrame(LinuxDebugger dbg, Address cfa, Address rip, DwarfParser dwarf, boolean finalFrame) {
|
||||
super(dbg.getCDebugger());
|
||||
this.cfa = cfa;
|
||||
this.rip = rip;
|
||||
this.dbg = dbg;
|
||||
this.dwarf = dwarf;
|
||||
this.finalFrame = finalFrame;
|
||||
}
|
||||
|
||||
// override base class impl to avoid ELF parsing
|
||||
@ -123,7 +131,19 @@ final public class LinuxAMD64CFrame extends BasicCFrame {
|
||||
return isValidFrame(nextCFA, context) ? nextCFA : null;
|
||||
}
|
||||
|
||||
private DwarfParser getNextDwarf(Address nextPC) {
|
||||
@Override
|
||||
public CFrame sender(ThreadProxy thread) {
|
||||
if (finalFrame) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ThreadContext context = thread.getContext();
|
||||
|
||||
Address nextPC = getNextPC(dwarf != null);
|
||||
if (nextPC == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
DwarfParser nextDwarf = null;
|
||||
|
||||
if ((dwarf != null) && dwarf.isIn(nextPC)) {
|
||||
@ -140,22 +160,16 @@ final public class LinuxAMD64CFrame extends BasicCFrame {
|
||||
}
|
||||
|
||||
if (nextDwarf != null) {
|
||||
nextDwarf.processDwarf(nextPC);
|
||||
try {
|
||||
nextDwarf.processDwarf(nextPC);
|
||||
} catch (DebuggerException e) {
|
||||
// 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).
|
||||
return new LinuxAMD64CFrame(dbg, null, nextPC, nextDwarf, true);
|
||||
}
|
||||
}
|
||||
|
||||
return nextDwarf;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CFrame sender(ThreadProxy thread) {
|
||||
ThreadContext context = thread.getContext();
|
||||
|
||||
Address nextPC = getNextPC(dwarf != null);
|
||||
if (nextPC == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
DwarfParser nextDwarf = getNextDwarf(nextPC);
|
||||
Address nextCFA = getNextCFA(nextDwarf, context);
|
||||
return isValidFrame(nextCFA, context) ? new LinuxAMD64CFrame(dbg, nextCFA, nextPC, nextDwarf)
|
||||
: null;
|
||||
@ -167,4 +181,5 @@ final public class LinuxAMD64CFrame extends BasicCFrame {
|
||||
private Address cfa;
|
||||
private LinuxDebugger dbg;
|
||||
private DwarfParser dwarf;
|
||||
private boolean finalFrame;
|
||||
}
|
||||
|
||||
@ -115,7 +115,7 @@ serviceability/sa/ClhsdbPmap.java 8193639 solaris-all
|
||||
serviceability/sa/ClhsdbPrintAll.java 8193639 solaris-all
|
||||
serviceability/sa/ClhsdbPrintAs.java 8193639 solaris-all
|
||||
serviceability/sa/ClhsdbPrintStatics.java 8193639 solaris-all
|
||||
serviceability/sa/ClhsdbPstack.java 8193639,8240956 solaris-all,linux-all
|
||||
serviceability/sa/ClhsdbPstack.java 8193639 solaris-all
|
||||
serviceability/sa/ClhsdbRegionDetailsScanOopsForG1.java 8193639 solaris-all
|
||||
serviceability/sa/ClhsdbScanOops.java 8193639,8235220,8230731 solaris-all,linux-x64,macosx-x64,windows-x64
|
||||
serviceability/sa/ClhsdbSource.java 8193639 solaris-all
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user