Skip to content

A set of fixes related to clang, aarch64 and musl pecularities of vmstructs stack unwinder #199

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Mar 30, 2025
Merged
5 changes: 4 additions & 1 deletion ddprof-lib/src/main/cpp/codeCache.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ class CodeCache {

void expand();
void makeImportsPatchable();
void saveImport(ImportId id, void** entry);
void saveImport(ImportId id, void** entry);

public:
explicit CodeCache(const char *name, short lib_index = -1,
Expand Down Expand Up @@ -177,6 +177,9 @@ class CodeCache {
}

int count() { return _count; }
CodeBlob* blob(int idx) {
return &_blobs[idx];
}
};

class CodeCacheArray {
Expand Down
14 changes: 10 additions & 4 deletions ddprof-lib/src/main/cpp/dwarf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ FrameDesc FrameDesc::empty_frame = {0, DW_REG_SP | EMPTY_FRAME_SIZE << 8,
FrameDesc FrameDesc::default_frame = {0, DW_REG_FP | LINKED_FRAME_SIZE << 8,
-LINKED_FRAME_SIZE,
-LINKED_FRAME_SIZE + DW_STACK_SLOT};
FrameDesc FrameDesc::default_clang_frame = {0, DW_REG_FP | LINKED_FRAME_CLANG_SIZE << 8, -LINKED_FRAME_CLANG_SIZE, -LINKED_FRAME_CLANG_SIZE + DW_STACK_SLOT};

DwarfParser::DwarfParser(const char *name, const char *image_base,
const char *eh_frame_hdr) {
Expand Down Expand Up @@ -398,12 +399,17 @@ int DwarfParser::parseExpression() {

void DwarfParser::addRecord(u32 loc, u32 cfa_reg, int cfa_off, int fp_off,
int pc_off) {
// sanity asserts for the values fitting into 16bit
assert(cfa_reg <= 0xffffffff);
assert(static_cast<u32>(cfa_off) <= 0xffffffff);
// Sanity asserts to be able to pack those two values into one u32 vq
// Assert that the cfa_reg fits in 8 bits (0 to 255)
assert(cfa_reg <= 0xFF);

// Assert that the cfa_off fits in a 24-bit signed range.
// Signed 24-bit integer range: -2^23 (-8,388,608) to 2^23 - 1 (8,388,607)
assert(cfa_off >= -8388608 && cfa_off <= 8388607);

// cfa_reg and cfa_off can be encoded to a single 32 bit value, considering the existing and supported systems
u32 cfa = static_cast<u16>(cfa_off) << 16 | static_cast<u16>(cfa_reg);
u32 cfa = static_cast<u32>(cfa_off) << 8 | static_cast<u32>(cfa_reg & 0xff);

if (_prev == NULL || (_prev->loc == loc && --_count >= 0) ||
_prev->cfa != cfa || _prev->fp_off != fp_off || _prev->pc_off != pc_off) {
_prev = addRecordRaw(loc, cfa, fp_off, pc_off);
Expand Down
14 changes: 7 additions & 7 deletions ddprof-lib/src/main/cpp/dwarf.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ const int DW_REG_SP = 7;
const int DW_REG_PC = 16;
const int EMPTY_FRAME_SIZE = DW_STACK_SLOT;
const int LINKED_FRAME_SIZE = 2 * DW_STACK_SLOT;
const int LINKED_FRAME_CLANG_SIZE = LINKED_FRAME_SIZE;

#elif defined(__i386__)

Expand All @@ -46,6 +47,7 @@ const int DW_REG_SP = 4;
const int DW_REG_PC = 8;
const int EMPTY_FRAME_SIZE = DW_STACK_SLOT;
const int LINKED_FRAME_SIZE = 2 * DW_STACK_SLOT;
const int LINKED_FRAME_CLANG_SIZE = LINKED_FRAME_SIZE;

#elif defined(__aarch64__)

Expand All @@ -55,13 +57,9 @@ const int DW_REG_FP = 29;
const int DW_REG_SP = 31;
const int DW_REG_PC = 30;
const int EMPTY_FRAME_SIZE = 0;

// aarch64 function prologue looks like this (if frame pointer is used):
// stp x29, x30, [sp, -16]! // Save FP (x29) and LR (x30)
// mov x29, sp // Set FP to SP
// ---
// LINKED_FRAME_SIZE should be 16
const int LINKED_FRAME_SIZE = 2 * DW_STACK_SLOT;
const int LINKED_FRAME_SIZE = 0;
// clang compiler uses different frame layout than GCC
const int LINKED_FRAME_CLANG_SIZE = 2 * DW_STACK_SLOT;

#else

Expand All @@ -72,6 +70,7 @@ const int DW_REG_SP = 1;
const int DW_REG_PC = 2;
const int EMPTY_FRAME_SIZE = 0;
const int LINKED_FRAME_SIZE = 0;
const int LINKED_FRAME_CLANG_SIZE = LINKED_FRAME_SIZE;

#endif

Expand All @@ -83,6 +82,7 @@ struct FrameDesc {

static FrameDesc empty_frame;
static FrameDesc default_frame;
static FrameDesc default_clang_frame;

static int comparator(const void *p1, const void *p2) {
FrameDesc *fd1 = (FrameDesc *)p1;
Expand Down
4 changes: 2 additions & 2 deletions ddprof-lib/src/main/cpp/profiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -252,10 +252,10 @@ CodeBlob *Profiler::findRuntimeStub(const void *address) {
return _runtime_stubs.findBlobByAddress(address);
}

bool Profiler::isAddressInCode(const void *pc) {
bool Profiler::isAddressInCode(const void *pc, bool include_stubs) {
if (CodeHeap::contains(pc)) {
return CodeHeap::findNMethod(pc) != NULL &&
!(pc >= _call_stub_begin && pc < _call_stub_end);
(include_stubs || !(pc >= _call_stub_begin && pc < _call_stub_end));
} else {
return _libs->findLibraryByAddress(pc) != NULL;
}
Expand Down
2 changes: 1 addition & 1 deletion ddprof-lib/src/main/cpp/profiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ class Profiler {
const char *getLibraryName(const char *native_symbol);
const char *findNativeMethod(const void *address);
CodeBlob *findRuntimeStub(const void *address);
bool isAddressInCode(const void *pc);
bool isAddressInCode(const void *pc, bool include_stubs = true);

static void segvHandler(int signo, siginfo_t *siginfo, void *ucontext);
static void busHandler(int signo, siginfo_t *siginfo, void *ucontext);
Expand Down
Loading
Loading