Skip to content
This repository was archived by the owner on Aug 27, 2022. It is now read-only.
/ lanai Public archive

Commit 67cf35e

Browse files
committedMar 27, 2020
8240956: SEGV in DwarfParser::process_dwarf after JDK-8234624
Reviewed-by: sspitsyn, kevinw
1 parent 83f7ee1 commit 67cf35e

File tree

5 files changed

+54
-29
lines changed

5 files changed

+54
-29
lines changed
 

‎src/jdk.hotspot.agent/linux/native/libsaproc/dwarf.cpp

+14-6
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@ bool DwarfParser::process_cie(unsigned char *start_of_entry, uint32_t id) {
7575

7676
char *augmentation_string = reinterpret_cast<char *>(_buf);
7777
bool has_ehdata = (strcmp("eh", augmentation_string) == 0);
78-
bool fde_encoded = (strchr(augmentation_string, 'R') != NULL);
7978
_buf += strlen(augmentation_string) + 1; // includes '\0'
8079
if (has_ehdata) {
8180
_buf += sizeof(void *); // Skip EH data
@@ -85,8 +84,16 @@ bool DwarfParser::process_cie(unsigned char *start_of_entry, uint32_t id) {
8584
_data_factor = static_cast<int>(read_leb(true));
8685
_return_address_reg = static_cast<enum DWARF_Register>(*_buf++);
8786

88-
if (fde_encoded) {
89-
uintptr_t augmentation_length = read_leb(false);
87+
if (strpbrk(augmentation_string, "LP") != NULL) {
88+
// Language personality routine (P) and Language Specific Data Area (LSDA:L)
89+
// are not supported because we need compliant Unwind Library Interface,
90+
// but we want to unwind without it.
91+
//
92+
// Unwind Library Interface (SysV ABI AMD64 6.2)
93+
// https://software.intel.com/sites/default/files/article/402129/mpx-linux64-abi.pdf
94+
return false;
95+
} else if (strchr(augmentation_string, 'R') != NULL) {
96+
read_leb(false); // augmentation length
9097
_encoding = *_buf++;
9198
}
9299

@@ -285,7 +292,8 @@ unsigned int DwarfParser::get_pc_range() {
285292
bool DwarfParser::process_dwarf(const uintptr_t pc) {
286293
// https://refspecs.linuxfoundation.org/LSB_3.0.0/LSB-PDA/LSB-PDA/ehframechpt.html
287294
_buf = _lib->eh_frame.data;
288-
while (true) {
295+
unsigned char *end = _lib->eh_frame.data + _lib->eh_frame.size;
296+
while (_buf <= end) {
289297
uint64_t length = get_entry_length();
290298
if (length == 0L) {
291299
return false;
@@ -310,12 +318,12 @@ bool DwarfParser::process_dwarf(const uintptr_t pc) {
310318

311319
// Process FDE
312320
parse_dwarf_instructions(pc_begin, pc, next_entry);
313-
break;
321+
return true;
314322
}
315323
}
316324

317325
_buf = next_entry;
318326
}
319327

320-
return true;
328+
return false;
321329
}

‎src/jdk.hotspot.agent/linux/native/libsaproc/libproc_impl.c

+1
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ bool read_eh_frame(struct ps_prochandle* ph, lib_info* lib) {
224224
lib->eh_frame.library_base_addr = lib->base;
225225
lib->eh_frame.v_addr = sh->sh_addr;
226226
lib->eh_frame.data = read_section_data(lib->fd, &ehdr, sh);
227+
lib->eh_frame.size = sh->sh_size;
227228
break;
228229
}
229230
}

‎src/jdk.hotspot.agent/linux/native/libsaproc/libproc_impl.h

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ typedef struct eh_frame_info {
3939
uintptr_t library_base_addr;
4040
uintptr_t v_addr;
4141
unsigned char* data;
42+
int size;
4243
} eh_frame_info;
4344

4445
// list of shared objects

‎src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/amd64/LinuxAMD64CFrame.java

+37-22
Original file line numberDiff line numberDiff line change
@@ -38,29 +38,37 @@ public static LinuxAMD64CFrame getTopFrame(LinuxDebugger dbg, Address rip, Threa
3838
DwarfParser dwarf = null;
3939

4040
if (libptr != null) { // Native frame
41+
dwarf = new DwarfParser(libptr);
4142
try {
42-
dwarf = new DwarfParser(libptr);
4343
dwarf.processDwarf(rip);
44-
cfa = ((dwarf.getCFARegister() == AMD64ThreadContext.RBP) &&
45-
!dwarf.isBPOffsetAvailable())
46-
? context.getRegisterAsAddress(AMD64ThreadContext.RBP)
47-
: context.getRegisterAsAddress(dwarf.getCFARegister())
48-
.addOffsetTo(dwarf.getCFAOffset());
4944
} catch (DebuggerException e) {
50-
// Bail out to Java frame case
45+
// DWARF processing should succeed when the frame is native
46+
// but it might fail if Common Information Entry (CIE) has language
47+
// personality routine and/or Language Specific Data Area (LSDA).
48+
return new LinuxAMD64CFrame(dbg, cfa, rip, dwarf, true);
5149
}
50+
cfa = ((dwarf.getCFARegister() == AMD64ThreadContext.RBP) &&
51+
!dwarf.isBPOffsetAvailable())
52+
? context.getRegisterAsAddress(AMD64ThreadContext.RBP)
53+
: context.getRegisterAsAddress(dwarf.getCFARegister())
54+
.addOffsetTo(dwarf.getCFAOffset());
5255
}
5356

5457
return (cfa == null) ? null
5558
: new LinuxAMD64CFrame(dbg, cfa, rip, dwarf);
5659
}
5760

5861
private LinuxAMD64CFrame(LinuxDebugger dbg, Address cfa, Address rip, DwarfParser dwarf) {
62+
this(dbg, cfa, rip, dwarf, false);
63+
}
64+
65+
private LinuxAMD64CFrame(LinuxDebugger dbg, Address cfa, Address rip, DwarfParser dwarf, boolean finalFrame) {
5966
super(dbg.getCDebugger());
6067
this.cfa = cfa;
6168
this.rip = rip;
6269
this.dbg = dbg;
6370
this.dwarf = dwarf;
71+
this.finalFrame = finalFrame;
6472
}
6573

6674
// override base class impl to avoid ELF parsing
@@ -123,7 +131,19 @@ private Address getNextCFA(DwarfParser nextDwarf, ThreadContext context) {
123131
return isValidFrame(nextCFA, context) ? nextCFA : null;
124132
}
125133

126-
private DwarfParser getNextDwarf(Address nextPC) {
134+
@Override
135+
public CFrame sender(ThreadProxy thread) {
136+
if (finalFrame) {
137+
return null;
138+
}
139+
140+
ThreadContext context = thread.getContext();
141+
142+
Address nextPC = getNextPC(dwarf != null);
143+
if (nextPC == null) {
144+
return null;
145+
}
146+
127147
DwarfParser nextDwarf = null;
128148

129149
if ((dwarf != null) && dwarf.isIn(nextPC)) {
@@ -140,22 +160,16 @@ private DwarfParser getNextDwarf(Address nextPC) {
140160
}
141161

142162
if (nextDwarf != null) {
143-
nextDwarf.processDwarf(nextPC);
144-
}
145-
146-
return nextDwarf;
147-
}
148-
149-
@Override
150-
public CFrame sender(ThreadProxy thread) {
151-
ThreadContext context = thread.getContext();
152-
153-
Address nextPC = getNextPC(dwarf != null);
154-
if (nextPC == null) {
155-
return null;
163+
try {
164+
nextDwarf.processDwarf(nextPC);
165+
} catch (DebuggerException e) {
166+
// DWARF processing should succeed when the frame is native
167+
// but it might fail if Common Information Entry (CIE) has language
168+
// personality routine and/or Language Specific Data Area (LSDA).
169+
return new LinuxAMD64CFrame(dbg, null, nextPC, nextDwarf, true);
170+
}
156171
}
157172

158-
DwarfParser nextDwarf = getNextDwarf(nextPC);
159173
Address nextCFA = getNextCFA(nextDwarf, context);
160174
return isValidFrame(nextCFA, context) ? new LinuxAMD64CFrame(dbg, nextCFA, nextPC, nextDwarf)
161175
: null;
@@ -167,4 +181,5 @@ public CFrame sender(ThreadProxy thread) {
167181
private Address cfa;
168182
private LinuxDebugger dbg;
169183
private DwarfParser dwarf;
184+
private boolean finalFrame;
170185
}

‎test/hotspot/jtreg/ProblemList.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ serviceability/sa/ClhsdbPmap.java 8193639 solaris-all
115115
serviceability/sa/ClhsdbPrintAll.java 8193639 solaris-all
116116
serviceability/sa/ClhsdbPrintAs.java 8193639 solaris-all
117117
serviceability/sa/ClhsdbPrintStatics.java 8193639 solaris-all
118-
serviceability/sa/ClhsdbPstack.java 8193639,8240956 solaris-all,linux-all
118+
serviceability/sa/ClhsdbPstack.java 8193639 solaris-all
119119
serviceability/sa/ClhsdbRegionDetailsScanOopsForG1.java 8193639 solaris-all
120120
serviceability/sa/ClhsdbScanOops.java 8193639,8235220,8230731 solaris-all,linux-x64,macosx-x64,windows-x64
121121
serviceability/sa/ClhsdbSource.java 8193639 solaris-all

0 commit comments

Comments
 (0)
This repository has been archived.