[GSoC weekly report#14]Describe the patch in detail (The final post)

This is the Final post in the GSoC series.

Sorry for the late post. These days I was busy on finding a job - -!

The GSoC2013 is over now, but my project is not finished. I will continue to work on GNU/Hurd.

There are two goals I will get before I graduate from school. One is submit the patch, get the patch merged in the GDB main code line. The other one is to write a document to describe the patch in detail, as say this post is not finished:)

(Not finished...)

[GSoC weekly report#13]fix patch

I have updated my patch according to Pedro Alves and Thomas Schwinge's comments this week.

The main part of change is described  in the mail-list, like

  • add comment to describe the different between gdb and gdbserver
  • adjust Makefile to re-use the exist files instead of using soft link
  • generate the patch based on the current upstream master branch
  • remove spurious blanks and revert back the '^L' (which I didn't know it has been used as the separate character for GNU Formating)
  • use #ifdef GDBSERVER as less as I can.

Now, I am running the testcase for native and gdbserver.

[GSoC weekly report#12]submit patch and fix patch

This week I have begun to submit patch.

First, I have submit a patch create some new files. Pedro Alves suggest me to re-use the exist file for easy maintaining and reviewing with the #ifdef GDBSERVER macro.  Then I changed the patch to satisfy that but I used soft link. Then he told me the soft link will be not available on all platform. Then I have studied some knowledge about autoconf to modify the confingure.ac the Makefile.in.

Now, I need do some more improving work. Such as, combination the memory-access interface to wrap gnu_xfer_memory, using  a single target backend between gdb and gdbserver ,adding comment to describe the design divergences before the macro GDBSERVER and some other helper function to wrap the rest interface.

[GSoC weekly report#11]here gdbserver go

Here gdbserver go!

I have put the code to github, under the branch of gdbserver.  The basic gdbserver on Hurd can set breakpoint, dump and modify memory variable  and dump registers. Before submit patches to the mainline, I need do more things.

Move the MIG-gen file out, now I have copy  exc_request_S.c  msg_reply_S.c  notify_S.c  process_reply_S.c directlly from the gdb directory. I should change this to generate them by mig. I haven't totally understand [gdb]/gdb/config/i386/i386gnu.mh and the use of autoconf, I need a little more time.

Adjust the code style. I should change the code style to GNU-style. (not complete)

 

[GSoC weekly report#10]implement basic gdbserver(3)

Last week I have implement fetch_register() relate functions. And I have finished memory-access functions. The problem I have met now is that the gdbserver can't resume from a breakpoint.

From my understanding now, the problem is not relate to the resume part but the inferior thread management.

Firstly, gdb will set breakpoint on dl_debug_state() to get dynamic load informations, from gdbserver with --remote-debug, I have found this

getpkt ("Z0,fad0,1"); [no ack sent]
putpkt ("$#00"); [noack mode]
getpkt ("mfad0,1"); [no ack sent]
putpkt ("$55#6a"); [noack mode]
getpkt ("Xfad0,0:"); [no ack sent]
before write, read data=55 89 e5 5d
after write, read data=55 89 e5 5d
putpkt ("$OK#9a"); [noack mode]
getpkt ("Xfad0,1:); [no ack sent]
before write, read data=55 89 e5 5d
after write, read data=cc 89 e5 5d
putpkt ("$OK#9a"); [noack mode]

($data#checksum) is the basic gdb remote protocol. And 0xfad0 is the address of _dl_debug_state on my hurd-box, and (Z0,addr,kind) command is request for inserting a memory breakpoint at addr.  But on hurd porting of gdb doesn't support Z0 command, so gdbserver reply ($#00) which means command not support. So gdb send anther request, (m,addr,size) to read the momery and (X,addr,size,value) to change the momery. In the last two line, we can see the 0xfad0 is change to 0xCC which present the int 3 intruction.

After I input a continue command on the gdb side, I will get this:

getpkt ("vCont;c"); [no ack sent]
putpkt("$T0505:e44d0201;04:084d0201;08:d1fa0* ;thread:0;#f3"); [noack mode]
...
getpkt ("P8=d0fa0000"); [no ack sent]
...
getpkt ("Xfad0,1:U"); [no ack sent]
before write, read data=cc 89 e5 5d
after write, read data=55 89 e5 5d
putpkt ("$OK#9a"); [noack mode]
getpkt ("QPassSignals:"); [no ack sent]
putpkt ("$OK#9a"); [noack mode]
getpkt ("vCont;s:0;c:0"); [no ack sent]

I have omit some not relate output. This part have show three things. Firstly, when gdbserver get the "vCont;c" command, it will send a response to the gdb with the thread's information like ("$T0505:e44d0201;04:084d0201;08:d1fa0* ;thread:0;#f3"); d1fa0* means the eip is at 0x0000fad1 (because we have set a breakpoint at 0x0000fad0). Secondly,  gdb will request gdbserver set the corrtect eip when recovery from the breakpoint, as we see ("P8=d0fa0000") to set eip to the origin value and remove the breakpoint  ("Xfad0,1:U").  Last, gdbserver will get a ("vCont;s:0;c:0") packet, this means 's' step thread-id '0' and 'c' continue thread-id '0'. This is the problem, gdb get this thread-id from the packet putpkt("$T0505:e44d0201;04:084d0201;08:d1fa0* ;thread:0;");

when in the porting of linux gdbserver, the packet are

putpkt("$T0505:e0faffbf;04:bcf9ffbf;08:51e51100;thread:p53fa.53fa;core:0;#2a");

getpkt ("vCont;s:p53fa.53fa");

Now I am digging into the problem.

================edit ===============================

the problem is caused by the wrong use of structure ptid_t in gdbserver. Seems the gdbserver regard the field lwp as field tid. I found a comment from lynx-low.c

/* brobecker/2010-06-21: It looks like the LWP field in ptids should be distinct for each thread (see write_ptid where it writes the thread ID from the LWP). So instead of storing the LynxOS tid in the tid field of the ptid, we store it in
the lwp field. */

I just modify code to adapt to this, the continue problem is gone.

[GSoC weekly report#9]implement basic gdbserver(2)

After I set breakpoint, the gdbserver will go wrong. In gdb side will complain that "PC register is not avaliable". 

This is main problem this week I meet. Now the gdb can attach to the gdbserver, and run the continue command. Sadly to say, it just can resume the   inferior one time because can't set breakpoint yet.

I think the problem is in fetch_register(), I will solve this soon.

(not finished...)

[GSoC weekly report#8]implement basic gdbserver

According to Youpi's adivice, I planing build gdbserver from scratch. As say, implement the basic gdbserver first, then add more feature one by one. But I also borrow code from the gdb part.

Reference for the implementation of the lynxOS port of gdbserver(because this port is much simpler than linux's), I have summarized the basic framework of how to implement a gdbserver.

1. Implement gnu_create_inferior(); which fork and exec the inferior and initialize the process list. The Hurd port of gdb have two specific core structures, such as structure inf which describe the state of the inferior and structure proc which describe the thread info of the inferior. And now I have put this two structures into gdbserver's process list and thread list reference by the pointer private_data and target_data respective.

2. Implement gnu_wait_1(). which does the actual work of set the wait_status. This is the most import function in gdbserver. Gdbserver only care of this three wait_kinds,TARGET_WAITKIND_EXITED,TARGET_WAITKIND_SIGNALED,TARGET_WAITKIND_STOPPED and should take care of the SIGNAL_TRAP when meet TARGET_WAITKING_STOPPED.

3. Implement the gnu_remuse() which recover  the inferior's execution.

Now I have meet a tiny problem, when I use gdb to attach gdbserver, it replied "Remote connection closed".  I will debug it and fix this. Before this weekend,  my gdbserver should work I think.