Skip to content

Commit

Permalink
Simplify "recovery" unwinding
Browse files Browse the repository at this point in the history
  • Loading branch information
peadar committed Aug 26, 2023
1 parent da17a6a commit bb5a39e
Showing 1 changed file with 16 additions and 17 deletions.
33 changes: 16 additions & 17 deletions process.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,17 @@
#include <sys/wait.h>
#include <signal.h>


#if defined(__amd64__)
#define BP(regs) (regs.rbp)
#define SP(regs) (regs.rsp)
#define IP(regs) (regs.rip)
#elif defined(__i386__)
#define BP(regs) regs.ebp
#define SP(regs) regs.esp
#define IP(regs) (regs.eip)
#elif defined(__aarch64__)
#define IP(regs) (regs.pc)
#endif

/*
* convert a gregset_t to an Elf::CoreRegs
Expand Down Expand Up @@ -933,30 +943,17 @@ ThreadStack::unwind(Process &p, Elf::CoreRegisters &regs, unsigned maxFrames)
// For ARM, the concept is the same, but we look at the link
// register rather than a pushd return address

#if defined(__amd64__)
#define BP(regs) (regs.rbp)
#define SP(regs) (regs.rsp)
#define IP(regs) (regs.rip)
#elif defined(__i386__)
#define BP(regs) regs.ebp
#define SP(regs) regs.esp
#define IP(regs) (regs.eip)
#elif defined(__aarch64__)
#define IP(regs) (regs.pc)
#endif

auto newRegs = prev.regs; // start with a copy of prev frames regs.

if (stack.size() == 1 || stack[stack.size() - 2].isSignalTrampoline) {
Dwarf::ProcessLocation prevlocation = prev.scopeIP(p);
Dwarf::ProcessLocation location(p, IP(newRegs));
if (!prevlocation.valid() || (location.valid() && (location.codeloc->phdr_->p_flags & PF_X) == 0)) {
Dwarf::ProcessLocation badip = { p, IP(prev.regs) };
if (!badip.valid() || (badip.codeloc->phdr_->p_flags & PF_X) == 0) {

#if defined(__amd64__) || defined(__i386__)
// get stack pointer in the current frame, and read content of TOS
auto sp = SP(prev.regs);
Elf::Addr ip;
auto in = p.io->read(sp, sizeof ip, (char *)&ip);
auto newRegs = prev.regs; // start with a copy of prev frames regs.
if (in == sizeof ip) {
SP(newRegs) = sp + sizeof ip;
IP(newRegs) = ip; // .. insn pointer.
Expand All @@ -983,6 +980,7 @@ ThreadStack::unwind(Process &p, Elf::CoreRegisters &regs, unsigned maxFrames)
ucontext_t uc;
};
auto sigframe = p.io->readObj<rt_sigframe>(prev.regs.sp);
Elf::CoreRegs newRegs;
for (int i = 0; i < 31; ++i)
newRegs.regs[i] = sigframe.uc.uc_mcontext.regs[i];
newRegs.sp = sigframe.uc.uc_mcontext.sp;
Expand Down Expand Up @@ -1041,6 +1039,7 @@ ThreadStack::unwind(Process &p, Elf::CoreRegisters &regs, unsigned maxFrames)
p.io->readObj(oldBp + ELF_BYTES, &newIp);
p.io->readObj(oldBp, &newBp);
if (newBp > oldBp && newIp > 4096) {
Elf::CoreRegisters newRegs = prev.regs;
SP(newRegs) = oldBp + ELF_BYTES * 2;
BP(newRegs) = newBp;
IP(newRegs) = newIp;
Expand Down

0 comments on commit bb5a39e

Please sign in to comment.