Skip to content
Permalink
Browse files

8240956: SEGV in DwarfParser::process_dwarf after JDK-8234624

Reviewed-by: sspitsyn, kevinw
  • Loading branch information
YaSuenag committed Mar 27, 2020
1 parent 83f7ee1 commit 67cf35ee221283086adc60f819759376dfd10893
@@ -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,29 +38,37 @@ public static LinuxAMD64CFrame getTopFrame(LinuxDebugger dbg, Address rip, Threa
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
: new LinuxAMD64CFrame(dbg, cfa, rip, dwarf);
}

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 @@ private Address getNextCFA(DwarfParser nextDwarf, ThreadContext context) {
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 @@ private DwarfParser getNextDwarf(Address nextPC) {
}

if (nextDwarf != null) {
nextDwarf.processDwarf(nextPC);
}

return nextDwarf;
}

@Override
public CFrame sender(ThreadProxy thread) {
ThreadContext context = thread.getContext();

Address nextPC = getNextPC(dwarf != null);
if (nextPC == null) {
return null;
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);
}
}

DwarfParser nextDwarf = getNextDwarf(nextPC);
Address nextCFA = getNextCFA(nextDwarf, context);
return isValidFrame(nextCFA, context) ? new LinuxAMD64CFrame(dbg, nextCFA, nextPC, nextDwarf)
: null;
@@ -167,4 +181,5 @@ public CFrame sender(ThreadProxy thread) {
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

0 comments on commit 67cf35e

Please sign in to comment.