Browse Source

Disambiguate recursive calls in step over

master
A.Olokhtonov 3 years ago
parent
commit
28c205c5ec
  1. 1
      .gitignore
  2. 27
      command.c
  3. 15
      res/003-recursion.c
  4. 1
      res/Makefile

1
.gitignore vendored

@ -2,3 +2,4 @@
build/ build/
res/001-simple res/001-simple
res/002-compilation-units res/002-compilation-units
res/003-recursion

27
command.c

@ -22,6 +22,7 @@ command_step(struct mi_process proc)
struct mi_sourcepoint *next_sp; struct mi_sourcepoint *next_sp;
do { do {
// TODO: step until source line changes (for active file)
ptrace(PTRACE_SINGLESTEP, proc.pid, 0, 0); ptrace(PTRACE_SINGLESTEP, proc.pid, 0, 0);
waitpid(proc.pid, 0, 0); waitpid(proc.pid, 0, 0);
regs = get_process_registers(proc); regs = get_process_registers(proc);
@ -51,25 +52,39 @@ command_next(struct mi_process proc)
struct mi_sourcepoint *next_sp; struct mi_sourcepoint *next_sp;
do { do {
// TODO: step until source line changes (for active file)
ptrace(PTRACE_SINGLESTEP, proc.pid, 0, 0); ptrace(PTRACE_SINGLESTEP, proc.pid, 0, 0);
waitpid(proc.pid, 0, 0); waitpid(proc.pid, 0, 0);
regs = get_process_registers(proc); regs = get_process_registers(proc);
long instruction = ptrace(PTRACE_PEEKDATA, proc.pid, regs.rip, NULL); long instruction = ptrace(PTRACE_PEEKDATA, proc.pid, regs.rip, NULL);
if (is_call_instruction(instruction)) { if (is_call_instruction(instruction)) {
u64 call_at = regs.rip; long base_address = regs.rbp;
// Do single step, get return address from stack, place breakpoint there, continue // NOTE do single step, get return address from stack, place breakpoint there, continue
ptrace(PTRACE_SINGLESTEP, proc.pid, 0, 0); ptrace(PTRACE_SINGLESTEP, proc.pid, 0, 0);
waitpid(proc.pid, 0, 0); waitpid(proc.pid, 0, 0);
regs = get_process_registers(proc); regs = get_process_registers(proc);
long return_address = ptrace(PTRACE_PEEKDATA, proc.pid, regs.rsp, NULL); long return_address = ptrace(PTRACE_PEEKDATA, proc.pid, regs.rsp, NULL);
long saved_instruction = place_breakpoint_at(proc, return_address);
run_until_breakpoint_and_restore(proc, return_address, saved_instruction);
// TODO: disambiguate recursive calls
regs = get_process_registers(proc); // NOTE: disambiguate recursive calls
for (;;) {
long saved_instruction = place_breakpoint_at(proc, return_address);
run_until_breakpoint_and_restore(proc, return_address, saved_instruction);
regs = get_process_registers(proc);
long actual_base_address = regs.rbp;
if (base_address == actual_base_address) {
break;
} else {
// NOTE: step to the next instruction after the return address, so that we can add a breakpoint there
ptrace(PTRACE_SINGLESTEP, proc.pid, 0, 0);
waitpid(proc.pid, 0, 0);
}
}
} }
// TODO: repXXX // TODO: repXXX

15
res/003-recursion.c

@ -0,0 +1,15 @@
static int
fact(int n)
{
if (n == 0 || n == 1) {
return(1);
}
return(n * fact(n - 1));
}
int
main(void)
{
int result = fact(5);
return(0);
}

1
res/Makefile

@ -1,3 +1,4 @@
all: all:
gcc -g -o 001-simple 001-simple.c gcc -g -o 001-simple 001-simple.c
gcc -g -o 002-compilation-units 002-compilation-units.c 002-compilation-units-impl.c gcc -g -o 002-compilation-units 002-compilation-units.c 002-compilation-units-impl.c
gcc -g -o 003-recursion 003-recursion.c

Loading…
Cancel
Save