diff --git a/embrace-android-sdk/src/main/cpp/3rdparty/libunwindstack-ndk/RegsArm.cpp b/embrace-android-sdk/src/main/cpp/3rdparty/libunwindstack-ndk/RegsArm.cpp index 1aaa08f569..30f27def73 100644 --- a/embrace-android-sdk/src/main/cpp/3rdparty/libunwindstack-ndk/RegsArm.cpp +++ b/embrace-android-sdk/src/main/cpp/3rdparty/libunwindstack-ndk/RegsArm.cpp @@ -43,6 +43,10 @@ uint64_t RegsArm::sp() { return regs_[ARM_REG_SP]; } +uint64_t RegsArm::lr() { + return regs_[ARM_REG_LR]; +} + void RegsArm::set_pc(uint64_t pc) { regs_[ARM_REG_PC] = pc; } diff --git a/embrace-android-sdk/src/main/cpp/3rdparty/libunwindstack-ndk/RegsArm64.cpp b/embrace-android-sdk/src/main/cpp/3rdparty/libunwindstack-ndk/RegsArm64.cpp index 0af9a1e392..0d2515292f 100644 --- a/embrace-android-sdk/src/main/cpp/3rdparty/libunwindstack-ndk/RegsArm64.cpp +++ b/embrace-android-sdk/src/main/cpp/3rdparty/libunwindstack-ndk/RegsArm64.cpp @@ -47,6 +47,10 @@ uint64_t RegsArm64::sp() { return regs_[ARM64_REG_SP]; } +uint64_t RegsArm64::lr() { + return regs_[ARM64_REG_LR]; +} + static uint64_t strip_pac(uint64_t pc, uint64_t mask) { // If the target is aarch64 then the return address may have been // signed using the Armv8.3-A Pointer Authentication extension. The diff --git a/embrace-android-sdk/src/main/cpp/3rdparty/libunwindstack-ndk/RegsX86.cpp b/embrace-android-sdk/src/main/cpp/3rdparty/libunwindstack-ndk/RegsX86.cpp index 4d3c246a41..8e732eb0a2 100644 --- a/embrace-android-sdk/src/main/cpp/3rdparty/libunwindstack-ndk/RegsX86.cpp +++ b/embrace-android-sdk/src/main/cpp/3rdparty/libunwindstack-ndk/RegsX86.cpp @@ -42,6 +42,10 @@ uint64_t RegsX86::sp() { return regs_[X86_REG_SP]; } +uint64_t RegsX86::lr() { + return 0; +} + void RegsX86::set_pc(uint64_t pc) { regs_[X86_REG_PC] = static_cast(pc); } diff --git a/embrace-android-sdk/src/main/cpp/3rdparty/libunwindstack-ndk/RegsX86_64.cpp b/embrace-android-sdk/src/main/cpp/3rdparty/libunwindstack-ndk/RegsX86_64.cpp index 26d9f6578a..d796714b1b 100644 --- a/embrace-android-sdk/src/main/cpp/3rdparty/libunwindstack-ndk/RegsX86_64.cpp +++ b/embrace-android-sdk/src/main/cpp/3rdparty/libunwindstack-ndk/RegsX86_64.cpp @@ -43,6 +43,10 @@ uint64_t RegsX86_64::sp() { return regs_[X86_64_REG_SP]; } +uint64_t RegsX86_64::lr() { + return 0; +} + void RegsX86_64::set_pc(uint64_t pc) { regs_[X86_64_REG_PC] = pc; } diff --git a/embrace-android-sdk/src/main/cpp/3rdparty/libunwindstack-ndk/include/unwindstack/Regs.h b/embrace-android-sdk/src/main/cpp/3rdparty/libunwindstack-ndk/include/unwindstack/Regs.h index bc7dab57f4..0f8028dd86 100644 --- a/embrace-android-sdk/src/main/cpp/3rdparty/libunwindstack-ndk/include/unwindstack/Regs.h +++ b/embrace-android-sdk/src/main/cpp/3rdparty/libunwindstack-ndk/include/unwindstack/Regs.h @@ -58,6 +58,7 @@ class Regs { virtual void* RawData() = 0; virtual uint64_t pc() = 0; virtual uint64_t sp() = 0; + virtual uint64_t lr() = 0; // embrace added virtual void set_pc(uint64_t pc) = 0; virtual void set_sp(uint64_t sp) = 0; diff --git a/embrace-android-sdk/src/main/cpp/3rdparty/libunwindstack-ndk/include/unwindstack/RegsArm.h b/embrace-android-sdk/src/main/cpp/3rdparty/libunwindstack-ndk/include/unwindstack/RegsArm.h index 5596605d04..71f6e13b5c 100644 --- a/embrace-android-sdk/src/main/cpp/3rdparty/libunwindstack-ndk/include/unwindstack/RegsArm.h +++ b/embrace-android-sdk/src/main/cpp/3rdparty/libunwindstack-ndk/include/unwindstack/RegsArm.h @@ -43,6 +43,7 @@ class RegsArm : public RegsImpl { uint64_t pc() override; uint64_t sp() override; + uint64_t lr() override; void set_pc(uint64_t pc) override; void set_sp(uint64_t sp) override; diff --git a/embrace-android-sdk/src/main/cpp/3rdparty/libunwindstack-ndk/include/unwindstack/RegsArm64.h b/embrace-android-sdk/src/main/cpp/3rdparty/libunwindstack-ndk/include/unwindstack/RegsArm64.h index d12a0437ae..8b3e0f5f67 100644 --- a/embrace-android-sdk/src/main/cpp/3rdparty/libunwindstack-ndk/include/unwindstack/RegsArm64.h +++ b/embrace-android-sdk/src/main/cpp/3rdparty/libunwindstack-ndk/include/unwindstack/RegsArm64.h @@ -44,6 +44,7 @@ class RegsArm64 : public RegsImpl { uint64_t pc() override; uint64_t sp() override; + uint64_t lr() override; void set_pc(uint64_t pc) override; void set_sp(uint64_t sp) override; diff --git a/embrace-android-sdk/src/main/cpp/3rdparty/libunwindstack-ndk/include/unwindstack/RegsX86.h b/embrace-android-sdk/src/main/cpp/3rdparty/libunwindstack-ndk/include/unwindstack/RegsX86.h index d8245eef8f..174aca12da 100644 --- a/embrace-android-sdk/src/main/cpp/3rdparty/libunwindstack-ndk/include/unwindstack/RegsX86.h +++ b/embrace-android-sdk/src/main/cpp/3rdparty/libunwindstack-ndk/include/unwindstack/RegsX86.h @@ -46,6 +46,7 @@ class RegsX86 : public RegsImpl { uint64_t pc() override; uint64_t sp() override; + uint64_t lr() override; void set_pc(uint64_t pc) override; void set_sp(uint64_t sp) override; diff --git a/embrace-android-sdk/src/main/cpp/3rdparty/libunwindstack-ndk/include/unwindstack/RegsX86_64.h b/embrace-android-sdk/src/main/cpp/3rdparty/libunwindstack-ndk/include/unwindstack/RegsX86_64.h index 90fee939c5..06ea3097f0 100644 --- a/embrace-android-sdk/src/main/cpp/3rdparty/libunwindstack-ndk/include/unwindstack/RegsX86_64.h +++ b/embrace-android-sdk/src/main/cpp/3rdparty/libunwindstack-ndk/include/unwindstack/RegsX86_64.h @@ -46,6 +46,7 @@ class RegsX86_64 : public RegsImpl { uint64_t pc() override; uint64_t sp() override; + uint64_t lr() override; void set_pc(uint64_t pc) override; void set_sp(uint64_t sp) override; diff --git a/embrace-android-sdk/src/main/cpp/file_writer.c b/embrace-android-sdk/src/main/cpp/file_writer.c index bd61363e23..e281ab5a8e 100644 --- a/embrace-android-sdk/src/main/cpp/file_writer.c +++ b/embrace-android-sdk/src/main/cpp/file_writer.c @@ -41,6 +41,7 @@ static const char *kFunctionNameKey = "function_name"; static const char *kRelPcKey = "rel_pc"; static const char *kPcKey = "pc"; static const char *kSpKey = "sp"; +static const char *kLrKey = "lr"; static const char *kStartKey = "start"; static const char *kEndKey = "end"; static const char *kOffsetKey = "offset"; @@ -148,6 +149,7 @@ void emb_log_frame_dbg_info(int i, emb_sframe *frame) { EMB_LOGDEV("rel_pc: 0x%lx", (unsigned long) frame->rel_pc); EMB_LOGDEV("pc: 0x%lx", (unsigned long) frame->pc); EMB_LOGDEV("sp: 0x%lx", (unsigned long) frame->sp); + EMB_LOGDEV("lr: 0x%lx", (unsigned long) frame->lr); EMB_LOGDEV("start: 0x%lx", (unsigned long) frame->start); EMB_LOGDEV("end: 0x%lx", (unsigned long) frame->end); EMB_LOGDEV("offset: 0x%lx", (unsigned long) frame->offset); @@ -245,6 +247,7 @@ char *emb_crash_to_json(emb_crash *crash) { json_object_set_number(frame_object, kRelPcKey, (unsigned long) frame.rel_pc); json_object_set_number(frame_object, kPcKey, (unsigned long) frame.pc); json_object_set_number(frame_object, kSpKey, (unsigned long) frame.sp); + json_object_set_number(frame_object, kLrKey, (unsigned long) frame.lr); json_object_set_number(frame_object, kStartKey, (unsigned long) frame.start); json_object_set_number(frame_object, kEndKey, (unsigned long) frame.end); json_object_set_number(frame_object, kOffsetKey, (unsigned long) frame.offset); diff --git a/embrace-android-sdk/src/main/cpp/stack_frames.h b/embrace-android-sdk/src/main/cpp/stack_frames.h index 923144ac24..e42068f707 100644 --- a/embrace-android-sdk/src/main/cpp/stack_frames.h +++ b/embrace-android-sdk/src/main/cpp/stack_frames.h @@ -82,6 +82,7 @@ typedef struct { uint64_t rel_pc; uint64_t pc; uint64_t sp; + uint64_t lr; // only populated for the first frame. uint64_t function_offset; char function_name[EMB_FRAME_STR_SIZE]; diff --git a/embrace-android-sdk/src/main/cpp/unwinders/unwinder_stack.cpp b/embrace-android-sdk/src/main/cpp/unwinders/unwinder_stack.cpp index da8c23f1d4..732e83cc81 100644 --- a/embrace-android-sdk/src/main/cpp/unwinders/unwinder_stack.cpp +++ b/embrace-android-sdk/src/main/cpp/unwinders/unwinder_stack.cpp @@ -30,8 +30,16 @@ emb_process_stack(emb_env *env, siginfo_t *info, void *user_context) { if (unwindSuccessful) { int i = 0; + + for (const auto &frame: android_unwinder_data.frames) { emb_sframe *data = &stacktrace[i++]; + + // populate the link register for the first value only + if (i == 0 && android_unwinder_data.saved_initial_regs.has_value()) { + data->lr = android_unwinder_data.saved_initial_regs->get()->lr(); + } + data->frame_addr = frame.pc; const auto map_info = frame.map_info; emb_strncpy(data->build_id, map_info->GetPrintableBuildID().c_str(), EMB_FRAME_STR_SIZE);