Already talked about this with Ron -- there's going to be a negotiation message at the beginning of a debugging session which will enable those communications when being debugged.
On Wed, Aug 10, 2016, 13:01 Barret Rhoden <[email protected]> wrote: > Another question: > > Whenever we create a thread, we're now calling d9s_notify_add_thread(), > which does a syscall, writing to a pipe that no one might be listening > on. If I create 10k threads or something, that might eventually > block. Plus, we now have a syscall in the thread creation path. > > Instead of always emitting, can we emit only when we are actively being > debugged? And when GDB initially connects to us, we can give it a list > of all existing threads. We do something similar in perf. When perf > record starts, we emit a bunch of samples saying which processes > exist. When we're tracing, we emit the samples on the fly. When we > aren't tracing, we just check a variable that tells us not to emit > (roughly). > > Barret > > > On 2016-08-10 at 19:21 "'Christopher Koch' via Akaros" > <[email protected]> wrote: > > Thanks for all the comments! It'll be a day or so before I fix > > everything up -- I'd actually started changing gdbserver from async > > back to sync again like you're also suggesting. Async *was* a hard > > requirement when I started, but I've since changed the protocol such > > that it's not actually a requirement anymore. > > > > On Wed, Aug 10, 2016, 12:17 Barret Rhoden <[email protected]> > > wrote: > > > > > Hi - > > > > > > Patch 4 comments. > > > > > > > From 4127acb18d0ce2e19bb4f3b6bf491b162c3c13f3 Mon Sep 17 00:00:00 > > > > 2001 From: Christopher Koch <[email protected]> > > > > Date: Thu, 4 Aug 2016 14:18:28 -0700 > > > > Subject: parlib/debug: Added ability to store memory and > > > > single-step. > > > > > > > > Removed some debugging print messages. > > > > > > > > Change-Id: I4263112b2e340ea02e56c273529de291a22ba9dc > > > > Signed-off-by: Christopher Koch <[email protected]> > > > > --- > > > > tests/Makefile | 2 +- > > > > user/parlib/debug.c | 68 > > > ++++++++++++++++++++++++++++++---- > > > > user/parlib/include/parlib/debug.h | 13 ++++--- > > > > user/parlib/include/parlib/x86/debug.h | 2 + > > > > user/parlib/include/parlib/x86/trap.h | 1 + > > > > user/parlib/thread0_sched.c | 1 + > > > > user/parlib/x86/debug.c | 24 ++++++++++++ > > > > 7 files changed, 97 insertions(+), 14 deletions(-) > > > > > > > > diff --git a/tests/Makefile b/tests/Makefile > > > > index 3127f376e4f2..aabaaa8ebff0 100644 > > > > --- a/tests/Makefile > > > > +++ b/tests/Makefile > > > > @@ -5,7 +5,7 @@ all: > > > > # TODO: when we clean this up, if we ditch OBJDIR, change the > > > > root > > > makefile > > > > TESTS_DIR = tests > > > > > > > > -CFLAGS_TESTS += $(CFLAGS_USER) -g > > > > +CFLAGS_TESTS += $(CFLAGS_USER) -g -ggdb -O0 > > > > > > Is the -O0 still necessary? I'd rather not build our tests like > > > that. > > > > > > If you want to set CFLAGS_TESTS for your own use (and not for the > > > repo), you can do so in your Makelocal, which isn't under version > > > control. > > > > > > > TESTS_CXXFLAGS += $(CXXFLAGS_USER) -g -std=gnu++11 > > > > > > > > TESTS_LDLIBS := -lpthread -lvmm -lbenchutil -lm -liplib -lndblib > > > > diff --git a/user/parlib/debug.c b/user/parlib/debug.c > > > > index 3395524e7e96..5117acb593f6 100644 > > > > --- a/user/parlib/debug.c > > > > +++ b/user/parlib/debug.c > > > > @@ -92,7 +92,6 @@ static void debug_read_handler(struct > > > > event_queue > > > *ev_q); > > > > static int debug_send_packet(int fd, void *data, size_t size); > > > > static int debug_send_error(uint32_t errnum); > > > > static int debug_send_response(struct d9_header *packet); > > > > -static void *d9_read_packet(struct d9_header *hdr); > > > > > > You can squash this and other fixups into older commits in this > > > patchset. > > > > > > > static int d9s_treadmem(struct d9_header *hdr, void *data); > > > > static int d9s_tstoremem(struct d9_header *hdr, void *data); > > > > static int d9s_tfetchreg(struct d9_header *hdr, void *data); > > > > @@ -303,8 +302,12 @@ int d9s_store_memory(const struct > > > > d9_tstoremem *req) } > > > > > > > > /* d9s_resume is the d9_ops func called to fulfill a TRESUME > > > > request. */ -void d9s_resume(void) > > > > +void d9s_resume(bool singlestep) > > > > { > > > > + if (singlestep) > > > > + uthread_apply_all(uthread_enable_single_step); > > > > + else > > > > + uthread_apply_all(uthread_disable_single_step); > > > > > > Does single-step need to be applied to every thread, or just the > > > thread that triggered the breakpoint? From our discussions, I > > > thought we'd single-step the thread that hit the breakpoint, and > > > then the others would just stop and start subject to whatever > > > stop-the-world policy we came up with. > > > > > > As you saw below, if we need to single-step arbitrary uthreads, > > > we're going to run into problems if they are SW or VM ctxs. > > > > > > Barret > > > > > > > > > > > > > > > > uthread_apply_all(uthread_runnable); > > > > } > > > > > > > > @@ -366,6 +369,7 @@ int d9s_tresume(struct d9_header *hdr, void > > > > *data) { > > > > int ret; > > > > struct d9_header *rpack; > > > > + struct d9_tresume *dtr = (struct d9_tresume *) (hdr + 1); > > > > > > > > if (d9_ops == NULL || d9_ops->resume == NULL) > > > > return debug_send_error(EBADF /* TODO: better error > > > > code > > > */); > > > > @@ -379,7 +383,7 @@ int d9s_tresume(struct d9_header *hdr, void > > > > *data) free(rpack); > > > > > > > > /* Call user-supplied routine. */ > > > > - d9_ops->resume(); > > > > + d9_ops->resume(dtr->singlestep); > > > > return ret; > > > > } > > > > > > > > @@ -618,7 +622,7 @@ void *d9c_read_thread(void *arg) > > > > * Investigate what the largest memory chunk gdb > > > > will ask > > > for is. */ > > > > rlen = read(fd, buf+bufindex, 4096); > > > > if (rlen <= 0) { > > > > - perror("d9 read"); > > > > + /* TODO(chrisko): error message? */ > > > > return NULL; > > > > } > > > > > > > > @@ -683,6 +687,52 @@ void d9c_init(struct d9c_ops *ops) > > > > clt_msg_handlers[D9_HANDLER(D9_TADDTHREAD)] = > > > > &d9c_taddthread; } > > > > > > > > +/* d9c_store_memory communicates with the 2LS to store from an > > > > address > > > in > > > > + * memory. */ > > > > +int d9c_store_memory(int fd, uintptr_t address, const void > > > > *const data, > > > > + uint32_t length) > > > > +{ > > > > + size_t return_packet_size; > > > > + struct d9_header *hdr; > > > > + struct d9_tstoremem *req; > > > > + > > > > + hdr = alloc_packet(sizeof(struct d9_tstoremem), > > > > D9_TSTOREMEM); > > > > + if (hdr == NULL) > > > > + return -1; > > > > + > > > > + req = (struct d9_tstoremem *) (hdr + 1); > > > > + req->address = address; > > > > + req->length = length; > > > > + memcpy(&(req->data), data, length); > > > > + > > > > + int ret = debug_send_packet(fd, hdr, hdr->size); > > > > + > > > > + /* Provide space for the message to be stored in. */ > > > > + return_packet_size = sizeof(struct d9_header) + > > > > + MAX(sizeof(struct d9_rstoremem), sizeof(struct > > > > d9_rerror)); > > > > + char pkt_buf[return_packet_size]; > > > > + > > > > + /* Set globals */ > > > > + response_header = (struct d9_header *) pkt_buf; > > > > + > > > > + /* Wait for response message. */ > > > > + uth_mutex_lock(sync_lock); > > > > + while (new_message != 1) > > > > + uth_cond_var_wait(sync_cv, sync_lock); > > > > + > > > > + /* Got response. */ > > > > + if (check_error_packet(response_header, D9_RSTOREMEM)) { > > > > + perror("d9 store memory"); > > > > + ret = -1; > > > > + } else { > > > > + ret = 0; > > > > + } > > > > + > > > > + new_message = 0; > > > > + uth_mutex_unlock(sync_lock); > > > > + return ret; > > > > +} > > > > + > > > > /* d9c_read_memory communicates with the 2LS to read from an > > > > address in > > > memory. > > > > */ > > > > int d9c_read_memory(int fd, uintptr_t address, uint32_t length, > > > > uint8_t > > > *buf) > > > > @@ -818,18 +868,20 @@ int d9c_fetch_registers(int fd, uint64_t > > > > tid, > > > struct d9_regs *regs) > > > > return ret; > > > > } > > > > > > > > -/* d9c_resume tells the 2LS to resume all threads. > > > > - * > > > > - * TODO(chrisko): resume w/ hardware-step enabled. */ > > > > -int d9c_resume(int fd) > > > > +/* d9c_resume tells the 2LS to resume all threads. */ > > > > +int d9c_resume(int fd, bool singlestep) > > > > { > > > > size_t return_packet_size; > > > > struct d9_header *hdr; > > > > + struct d9_tresume *req; > > > > > > > > hdr = alloc_packet(sizeof(struct d9_tresume), D9_TRESUME); > > > > if (hdr == NULL) > > > > return -1; > > > > > > > > + req = (struct d9_tresume *) (hdr + 1); > > > > + req->singlestep = singlestep; > > > > + > > > > int ret = debug_send_packet(fd, hdr, hdr->size); > > > > > > > > /* Block on getting a response packet. */ > > > > diff --git a/user/parlib/include/parlib/debug.h > > > b/user/parlib/include/parlib/debug.h > > > > index c4e6a0eb8629..a068e1d8dbfe 100644 > > > > --- a/user/parlib/include/parlib/debug.h > > > > +++ b/user/parlib/include/parlib/debug.h > > > > @@ -70,7 +70,9 @@ struct d9_tstorereg { > > > > > > > > struct d9_rstorereg {}; > > > > > > > > -struct d9_tresume {}; > > > > +struct d9_tresume { > > > > + bool singlestep:1; > > > > +}; > > > > > > > > struct d9_rresume {}; > > > > > > > > @@ -96,7 +98,7 @@ struct d9_ops { > > > > int (*store_memory)(const struct d9_tstoremem *req); > > > > int (*fetch_registers)(struct uthread *t, struct d9_regs > > > > *resp); int (*store_registers)(struct uthread *t, struct d9_regs > > > > *resp); > > > > - void (*resume)(void); > > > > + void (*resume)(bool singlestep); > > > > }; > > > > > > > > /* gdbserver ops. > > > > @@ -118,7 +120,7 @@ void d9s_init(struct d9_ops *debug_ops); > > > > /* Implementations of d9_ops. */ > > > > int d9s_read_memory(const struct d9_treadmem *req, struct > > > > d9_rreadmem > > > *resp); > > > > int d9s_store_memory(const struct d9_tstoremem *req); > > > > -void d9s_resume(void); > > > > +void d9s_resume(bool singlestep); > > > > > > > > /* Helpers to send messages from 2LS to gdbserver. */ > > > > int d9s_notify_hit_breakpoint(uint64_t tid, uint64_t address); > > > > @@ -130,7 +132,8 @@ void *d9c_read_thread(void *arg); > > > > > > > > /* Helpers to send messages from gdbserver to 2LS. */ > > > > int d9c_read_memory(int fd, uintptr_t address, uint32_t length, > > > > uint8_t > > > *buf); > > > > -int d9c_store_memory(int fd, uintptr_t address, void *data, > > > > uint32_t > > > length); > > > > +int d9c_store_memory(int fd, uintptr_t address, const void > > > > *const data, > > > > + uint32_t length); > > > > int d9c_fetch_registers(int fd, uint64_t tid, struct d9_regs > > > > *regs); int d9c_store_registers(int fd, uint64_t tid, struct > > > > d9_regs *regs); -int d9c_resume(int fd); > > > > +int d9c_resume(int fd, bool singlestep); > > > > diff --git a/user/parlib/include/parlib/x86/debug.h > > > b/user/parlib/include/parlib/x86/debug.h > > > > index 2c75a4f2093c..46400779344c 100644 > > > > --- a/user/parlib/include/parlib/x86/debug.h > > > > +++ b/user/parlib/include/parlib/x86/debug.h > > > > @@ -29,5 +29,7 @@ struct d9_regs { > > > > uint64_t reg_gs; > > > > }; > > > > > > > > +void uthread_disable_single_step(struct uthread *t); > > > > +void uthread_enable_single_step(struct uthread *t); > > > > int d9_fetch_registers(struct uthread *t, struct d9_regs *resp); > > > > int d9_store_registers(struct uthread *t, struct d9_regs *resp); > > > > diff --git a/user/parlib/include/parlib/x86/trap.h > > > b/user/parlib/include/parlib/x86/trap.h > > > > index 3c9e907032db..957ec4e214be 100644 > > > > --- a/user/parlib/include/parlib/x86/trap.h > > > > +++ b/user/parlib/include/parlib/x86/trap.h > > > > @@ -12,6 +12,7 @@ > > > > __BEGIN_DECLS > > > > > > > > #define HW_TRAP_DIV_ZERO 0 > > > > +#define HW_TRAP_DEBUG 1 > > > > #define HW_TRAP_BRKPT 3 > > > > #define HW_TRAP_GP_FAULT 13 > > > > #define HW_TRAP_PAGE_FAULT 14 > > > > diff --git a/user/parlib/thread0_sched.c > > > > b/user/parlib/thread0_sched.c index ef993392c2b9..3d4d912472bf > > > > 100644 --- a/user/parlib/thread0_sched.c > > > > +++ b/user/parlib/thread0_sched.c > > > > @@ -133,6 +133,7 @@ static void thread0_thread_refl_fault(struct > > > > uthread > > > *uth, > > > > refl_error(uth, trap_nr, err, aux); > > > > break; > > > > case HW_TRAP_BRKPT: > > > > + case HW_TRAP_DEBUG: > > > > /* We only have one thread, no need to stop other > > > > threads. > > > */ > > > > uthread_has_blocked(uth, 0); > > > > d9s_notify_hit_breakpoint(uth->id, 0); > > > > diff --git a/user/parlib/x86/debug.c b/user/parlib/x86/debug.c > > > > index 7dd7b589b04f..8c005fbfff34 100644 > > > > --- a/user/parlib/x86/debug.c > > > > +++ b/user/parlib/x86/debug.c > > > > @@ -1,4 +1,28 @@ > > > > #include <parlib/arch/debug.h> > > > > +#include <parlib/assert.h> > > > > +#include <ros/arch/mmu.h> > > > > + > > > > +void uthread_enable_single_step(struct uthread *t) > > > > +{ > > > > + switch (t->u_ctx.type) { > > > > + case ROS_HW_CTX: > > > > + t->u_ctx.tf.hw_tf.tf_rflags |= FL_TF; > > > > + break; > > > > + default: > > > > + panic("bad context type\n"); > > > > + } > > > > +} > > > > + > > > > +void uthread_disable_single_step(struct uthread *t) > > > > +{ > > > > + switch (t->u_ctx.type) { > > > > + case ROS_HW_CTX: > > > > + t->u_ctx.tf.hw_tf.tf_rflags &= ~FL_TF; > > > > + break; > > > > + default: > > > > + panic("bad context type\n"); > > > > + } > > > > +} > > > > > > > > /* TODO(chrisko): add a way to signal that a register isn't > > > > supplied > > > for sw > > > > * contexts; because gdbserver has a notion of not knowing a > > > > register's > > > value. > > > > -- > > > > 2.8.0.rc3.226.g39d4020 > > > > > > > > > > -- > > > You received this message because you are subscribed to the Google > > > Groups "Akaros" group. > > > To unsubscribe from this group and stop receiving emails from it, > > > send an email to [email protected]. > > > To post to this group, send email to [email protected]. > > > For more options, visit https://groups.google.com/d/optout. > > > > > -- > You received this message because you are subscribed to the Google Groups > "Akaros" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected]. > To post to this group, send email to [email protected]. > For more options, visit https://groups.google.com/d/optout. > -- Christopher Koch | Software Engineer | [email protected] | 650-214-3546 -- You received this message because you are subscribed to the Google Groups "Akaros" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. For more options, visit https://groups.google.com/d/optout.
