This is the mail archive of the gdb@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Multi-packet gdb server request/response - problem?


Hello guys!

After some hackery I think I understand a tiny bit of how remote
support works in gdb.
Request packet "s" ("c") is sent as a part of resume() as can be seen
from the following truss excerpt:

------------------
...
        -> remote_serial_write(0xffff80ffbfffef60, 0x5, 0x0, 0x0,
0x18, 0x203a74656b636170)
            -> serial_write(0xc195a0, 0xffff80ffbfffef60, 0x5, 0x0,
0x18, 0x203a74656b636170)
                -> ser_base_write(0xc195a0, 0xffff80ffbfffef60, 0x5,
0x0, 0x18, 0x203a74656b636170)
                    -> ser_unix_write_prim(0xc195a0,
0xffff80ffbfffef60, 0x5, 0x0, 0x18, 0x203a74656b636170)
write(9, " $ s # 7 3", 5)                       = 5
                     <- ser_unix_write_prim() = 5
            <- serial_write() = 0
        <- remote_serial_write() = 0
     <- putpkt() = 0
 <- remote_resume() = 0
...
------------------

However code in resume() does not actively wait for the response.
It is assumed (I think) that target_wait() will do the response handling.
And it initially does, because it does the following:
------------------
  for (t = current_target.beneath; t != NULL; t = t->beneath)
    {
      if (t->to_wait != NULL)
        {
          ptid_t retval = (*t->to_wait) (t, ptid, status, options);
...
------------------
Initially t->to_wait() is simply remote_wait() which indeed reads the response
packet and parses it.

At some point in the debugging session (not sure when but it does not matter),
I think gdb kicks in the OS-specific functions. For solaris, they are
found in sol-thread.c.
And t->to_wait() is no longer simple remote_wait() but is sol_thread_wait().

At this point, things go awry.
sol_thread_wait() contains the following stuff:
------------------
  save_ptid = inferior_ptid;
  old_chain = save_inferior_ptid ();

  inferior_ptid = thread_to_lwp (inferior_ptid, PIDGET (main_ph.ptid));
  if (PIDGET (inferior_ptid) == -1)
    inferior_ptid = procfs_first_available ();

...

  rtnval = beneath->to_wait (beneath, ptid, ourstatus, options);
------------------

The old remote_wait() function is hidden in the call of "beneath->to_wait()".
However the problem here is that thread_to_lwp() which precedes it is called
_before_ "beneath->to_wait()". And thread_to_lwp() invokes (among others)
target_read_memory() which in turn sends "m" request packet...

Looking at other *-thread.c sources (BSD, DEC, AIX etc.) they usually contain
call to "beneath->to_wait()" as their first thing. So I think the
logic in sol_thread_wait()
is flawed in that "beneath->to_wait()" is not called "early" enough.

I quickly hacked function sol_thread_wait() and removed all calls to
thread_to_lwp()
preceding "beneath->to_wait()". And the conversation with remote stub
is working now!
But now the ptid->lwp conversion is not done properly...

Anyone has any idea of how to overcome this flaw in sol_thread_wait()?

I.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]