summaryrefslogtreecommitdiffstats
path: root/debugger.c
diff options
context:
space:
mode:
authorMalfurious <m@lfurio.us>2023-10-07 02:07:04 -0400
committerMalfurious <m@lfurio.us>2024-04-24 13:31:08 -0400
commit5589a9e3afd51bdf3d8715fb09b1667c6773b73f (patch)
treed8e1d65d9c4337d2427a32c0134e1c4fe2273254 /debugger.c
parent3a8bf604bf4d086bdc4fee70a82371a338835222 (diff)
downloadmisplays-5589a9e3afd51bdf3d8715fb09b1667c6773b73f.tar.gz
misplays-5589a9e3afd51bdf3d8715fb09b1667c6773b73f.zip
Ignore breakpoints during singlestep
Due to new independent thread control, it is now possible and likely that breakpoints will be installed before singlesteps are waited upon to be completed. also clean detect_breakpoint with get_breakpoint. Signed-off-by: Malfurious <m@lfurio.us>
Diffstat (limited to 'debugger.c')
-rw-r--r--debugger.c33
1 files changed, 13 insertions, 20 deletions
diff --git a/debugger.c b/debugger.c
index b08faf6..b646dc4 100644
--- a/debugger.c
+++ b/debugger.c
@@ -110,26 +110,19 @@ static int detect_breakpoint(struct thread *th, int *restart) {
struct iovec ivregs = { &regs, sizeof(regs) };
ptrace(PTRACE_GETREGSET, th->id, NT_PRSTATUS, &ivregs);
- /* implement with get_breakpoint? */
- struct list *breaks = &th->proc->breakpoints;
- for (struct breakpoint *b = breaks->tail; b != breaks->end; b = b->prev) {
- if (b->installed && (regs.rip - 1 == b->address)) {
- regs.rip--;
- ptrace(PTRACE_SETREGSET, th->id, NT_PRSTATUS, &ivregs);
- b->hits++;
- ret = b->user;
-
- if (b->stack != 0 && b->stack != regs.rsp) {
- *restart = 1;
- }
- if (b->tid != 0 && b->tid != th->id) {
- *restart = 1;
- }
- if (!b->enabled) {
- *restart = 1;
- }
-
- break;
+ struct breakpoint *b = get_breakpoint(th->proc, regs.rip - 1);
+ if (b && b->installed && th->doing != PTRACE_SINGLESTEP) {
+ regs.rip--;
+ ptrace(PTRACE_SETREGSET, th->id, NT_PRSTATUS, &ivregs);
+ b->hits++; /* todo: consider whether this is firing too much */
+ ret = b->user;
+
+ if (b->stack != 0 && b->stack != regs.rsp) {
+ *restart = 1;
+ } else if (b->tid != 0 && b->tid != th->id) {
+ *restart = 1;
+ } else if (!b->enabled) {
+ *restart = 1;
}
}