Re: Debugging gdb with gdb

Piet/Pete Delaney
2002-02-04T23:13:17Z

On Mon, Feb 04, 2002 at 03:00:44PM -0800, Piet/Pete Delaney wrote:
> On Mon, Feb 04, 2002 at 03:01:27PM -0700, Kevin Buettner wrote:
> > On Feb 4, 12:23pm, Piet/Pete Delaney wrote:

I think I could likely remove the target cmd from the cmds in the tmp file,
print the name of the pty, and then target it myself from gdb prompt. I suppose
that's what you may have been suggeting.

-piet

> >
> > > Happen to have a trick to get the inferior GDB to wait for the attaching GDB
> > > to place breakpoints prior to the inferior setting up a remote debug session.
> > > skdb starts the inferior gdb with a named pipe (see attached), I'm thinking
> > > about adding a loop to spin till a global variable is set by the attaching
> > > gdb to indicate that the inferionr gdb can progress with setting up the
> > > remote connections and sent the 'g' packet.
> >
> > I don't understand why you need to do this. Why not just start up the
> > inferior gdb first and attach to it with another gdb while it's at the
> > prompt? Once you're attached, you can set breakpoints wherever you
> > like. After your breakpoints are set, do a ``continue'' and then
> > start entering your target connection commands in the inferior gdb.
> > Assuming you've placed a breakpoint somewhere along the execution path
> > that the inferior gdb will take when/after it connects, you'll be
> > stopped...
>
> skdb starts gdb with the -x option so that gdb will get cmds from a tmp file. The cmds
> targets the remote to a pty. I suppose I could disable the startup code. Adding a hang
> in gdb seems easier. Likely I'll add an option to the inferior gdb and enable the switch
> to hang before sending the 'g' packet and pass the new option via the execvp() args to gdb.
> The new option might come in handy for other bugs.
> ----------------------------------------------------------------------------------------------------
>
> stdin/stdout
> |
> |
> |
> ^
> / \
> / \
> / \
> / \
> / \
> / \ (ignored)
> +---------------+ pty +---------------+ telet +---------------+
> + gdb + <---> + skdb + <---------> + kdb +
> + + + + + +
> +---------------+ +---------------+ +---------------+
> | |
> \ /
> \ /
> \ /
> /tmp/tmpnam:
>
>
>
> ----------------------------------------------------------------------------------------------------
> /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
> * Function: pfork
> * Create a master/slave pty pair, fork and exec gdb with
> * -x fudged to point it to the slave pty in the parent
> * process space. Child will do the real work.
> * Parameters:
> * argc - number of gdb command line parameters
> * args - gdb's command line parameters
> * Returns:
> * file descriptor for master PTY on success or -1 on error
> \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
> int
> pfork (int argc, char ** args)
> {
> int pt;
>
> if ( (pt = open ("/dev/ptmx", O_RDWR)) >= 0 ) {
> if ( grantpt (pt) != -1 ) {
> if ( unlockpt (pt) != -1 ) {
> FILE * tf;
> char * tname = strdup (tmpnam (NULL));
> pid_t child;
>
> if ( tname == NULL ) {
> puts ("Oops!");
> return -1;
> } else if ( (tf = fopen (tname, "w")) == NULL ) {
> perror (tname);
> free (tname);
> return -1;
> }
>
> fprintf (tf,
> "shell rm %s\n"
> "set remotedebug %d\n"
> "set serialdebug %d\n"
> "target remote %s\n"
> "define lsmod\n"
> "set $mod = (struct module*)module_list\n"
> "while $mod != &kernel_module\n"
> "printf \"%%p\t%%s\\n\", (long)$mod, ($mod)->name\n"
> "set $mod = $mod->next\n"
> "end\nend\n",
> tname,
> ((debug & SKDB_DBG_REMOTE) != 0),
> ((debug & SKDB_DBG_SERIAL) != 0),
> ptsname(pt));
> fflush (tf);
>
> if ( (child = fork ()) > 0 ) {
> int i;
> char **gargs = calloc (argc+5, sizeof (char *));
> if ( gargs == NULL ) {
> kill (child, SIGTERM);
> exit (1);
> } else {
> gargs[0] = "gdb";
> gargs[1] = "-q";
> gargs[2] = "-x";
> gargs[3] = tname;
>
> close (pt);
>
> for ( i=0; i < argc ; i++ ) {
> gargs[i+4] = args[i];
> }
>
> gargs[i+4] = NULL;
>
> execvp ("gdb", gargs);
> kill (child, SIGTERM);
> exit (1);
> }
> /*NOTREACHED*/
> } else if ( child < 0 ) {
> perror ("fork");
> close (pt);
> pt = -1;
> }
>
> fclose (tf);
>
> free (tname);
> return (pt);
> } else {
> perror ("unlockpt");
> }
> } else {
> perror ("grantpt");
> }
> close (pt);
> }
>
> return (-1);
> }
> -----------------------------------------------------------------------------------------------------
>
> -piet