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

Ivo Raisr <[email protected]>
Newsgroups gmane.comp.gdb.devel
Message-ID <CANXv6=tByX3xbrKU-uiZwshHVW9k5NcWP5Etd+QDwCU7qe-wFw@mail.gmail.com>
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.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.