I think this code was originally written by Nate who is no longer with us. Looking at it, what I *think* it's doing starts in listen(). That sets up a poll queue event which listens for connection from gdb. When that gets triggered, that (slightly indirectly) calls connect which will check if somebody is already attached, and if not call the attach function. That will set up a poll queue event which waits for data to show up on the new connection. Once that happens, the incomingData method is called, and that sets up an event which will trigger at the next instruction boundary so that the remote GDB stub is operating synchronously with the rest of gem5 I think, and also so that it's not trying to look at state half way through an instruction. When that trap event fires, it calls the trap() method.
So at this point we know that there was a connect, we got sent data through it, and we're at an instruction boundary, if we're entering the debug loop because gdb connected to us. If we're entering the gdb loop for some other reason (in the comment there it mentions the kernel's debug stub running in the guest triggering a breakpoint) then that's what I think that "if" is for. If we aren't active (because we didn't call attach() yet, ie no gdb has connected to us), then record that we are in fact active. If we were already active, ie gdb was already talking to us, tell it we got a trap and it can send us commands. Regardless, then we try to read commands from gdb and execute them one by one. Getting commands is started by the recv(data) call in that function which eventually trickles down to a call to read() on the socket to retrieve a byte. If that blocks, then gdb hasn't told us what to do yet. In the case where the CPU has been told to wait for GDB, gem5 just blocks after the GDB stub has been created until something connects to it. I don't see any race condition here. If gem5 has been told to wait, it waits. If gdb has connected to it and hasn't told it to keep running, it blocks. If, on the other hand, somebody throws a BadClient exception, for instance because the data from gdb is malformed, then gdb will be disconnected and the command loop will exit. This prevents a rogue connection or a misbehaving client from jamming up the gdb server and locking the simulation from progressing. The client can attempt to reattach to continue debugging which would act like a connection reboot, flushing away the broken connection and starting over. Also commands which return false tell the command loop to exit. This is how the continue command breaks out of the loop so the simulation can progress. Gabe On Thu, Aug 6, 2020 at 5:25 PM Boris Shingarov via gem5-dev < [email protected]> wrote: > It gets worse: I am beginning to suspect that this race is what ultimately > causes the "xml for the wrong xlen" mystery (if the timing is unlucky, the > CSPR isn't set yet). > > -----"Boris Shingarov via gem5-dev" <[email protected]> wrote: ----- > To: [email protected] > From: "Boris Shingarov via gem5-dev" <[email protected]> > Date: 08/06/2020 08:14PM > Cc: "Boris Shingarov" <[email protected]> > Subject: [gem5-dev] Possible race condition (Remote GDB) > > It looks to me that there is a race condition inherent in the design of > DataEvent. > The effect is that, even when CPU.wait_for_gdb attr is set and after the > the RSP socket has connected, the relative timing of gdb's vs gem5's > execution may or may not lead to gdb's presence being ignored. It's like > "hey gdb,I know you already connected, but if you aren't quick enough that > the qSupported reaches the queue within N ms after connecting, I am going > ahead without you; (and no I am not telling you what N is)". > > It looks like one fundamental issue here is the historical packet-oriented > nature of RSP. But it also looks like remote_gdb.cc:434, > > if (!active) { > active = true; > } else { > // Tell remote host that an exception has occurred. > send(csprintf("S%02x", type).c_str()); > } > > plays a central role. > Can someone comment on how this is intended to work? I must admit the > comment above that code doesn't make sense to me. > > _______________________________________________ > gem5-dev mailing list -- [email protected] > To unsubscribe send an email to [email protected] > %(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s > _______________________________________________ > gem5-dev mailing list -- [email protected] > To unsubscribe send an email to [email protected] > %(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s >
_______________________________________________ gem5-dev mailing list -- [email protected] To unsubscribe send an email to [email protected] %(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s
