All of lore.kernel.org
 help / color / mirror / Atom feed
* anybody using pdb?
@ 2004-03-11  0:10 Christian Limpach
  2004-03-11  8:28 ` Keir Fraser
  0 siblings, 1 reply; 6+ messages in thread
From: Christian Limpach @ 2004-03-11  0:10 UTC (permalink / raw)
  To: xen-devel

[-- Attachment #1: Type: TEXT/PLAIN, Size: 1294 bytes --]

Hello!

I'd like to use pdb but it's not quite working as expected.

The 1st issue is that jumping to the debugger by pressing 'D' doesn't work
because this leaves serial interrupts blocked.  Maybe this is only the
case because I'm using lo/hi muxing but my guess is that it's not.  I've
implemented a work around which seems to work:  if pdb is entered by the
keypressed handler it will call a new serial_getc function if there's no
input in the rx ring.  I'm not sure if this is also necessary when
interacting with the debugger on a breakpoint or after a crash...

2nd issue is that the debugger doesn't work when hitting a breakpoint (and
possibly after a crash) which raises my question if anybody is actually
using the pdb code which is in unstable ;-)

Finally, nsplitd seems to be missing the part which connects it to the
serial port (it wants to connect to a host:port, I guess on a terminal
server...).  The 2nd attachment is a program which presents the cleared-bit
connection on stdin/stdout and the set-bit connection on a tcp port (option
-g to set the port).  It should also work from inetd or as a server (option
-p to set the server port) but I haven't really tested those modes (I at
first implemented the inetd/server modes and then decided that I prefer
stdin/stdout...).


[-- Attachment #2: pdb-diff.txt --]
[-- Type: TEXT/PLAIN, Size: 2848 bytes --]

===================================================================
RCS file: arch/i386/pdb-stub.c,v
retrieving revision 1.1
diff -up -r1.1 arch/i386/pdb-stub.c
--- arch/i386/pdb-stub.c	2004/03/10 21:14:55	1.1
+++ arch/i386/pdb-stub.c	2004/03/11 00:03:22
@@ -31,6 +31,7 @@ void pdb_put_packet (unsigned char *buff
 
 static int pdb_initialized = 0;
 static int pdb_serhnd      = -1;
+static int pdb_sermaster   = 0;
 
 #define RX_SIZE 32
 #define RX_MASK(_i) ((_i)&(RX_SIZE-1))
@@ -44,8 +45,12 @@ static inline void pdb_put_char(unsigned
 
 static inline unsigned char pdb_get_char(void)
 {
-    while ( rx_cons == rx_prod )
-        barrier();
+    if ( pdb_sermaster && rx_cons == rx_prod ) {
+	return serial_getc(pdb_serhnd);
+    } else {
+	while ( rx_cons == rx_prod )
+	    barrier();
+    }
     return rx_ring[RX_MASK(rx_cons++)];
 }
 
@@ -822,7 +827,9 @@ int pdb_handle_exception(int exceptionVe
 
 void pdb_key_pressed(u_char key, void *dev_id, struct pt_regs *regs) 
 {
+    pdb_sermaster = 1;
     pdb_handle_exception(KEYPRESS_EXCEPTION, regs);
+    pdb_sermaster = 0;
     return;
 }
 
===================================================================
RCS file: drivers/char/serial.c,v
retrieving revision 1.2
diff -up -r1.2 drivers/char/serial.c
--- drivers/char/serial.c	2004/03/10 23:16:01	1.2
+++ drivers/char/serial.c	2004/03/10 23:17:57
@@ -137,6 +137,24 @@ static inline void __serial_putc(uart_t 
     outb(c, uart->io_base + THR);
 }
 
+static inline unsigned char __serial_getc(uart_t *uart, int handle)
+{
+    unsigned char c;
+
+    for (;;) {
+	while ( (inb(uart->io_base + LSR) & LSR_DR) == 0 )
+	    barrier();
+
+	c = inb(uart->io_base + RBR);
+
+	if ( c & 0x80 && handle & SERHND_HI )
+	    break;
+	if ( (c & 0x80) == 0 && handle & SERHND_LO )
+	    break;
+    }
+    return c & 0x7f;
+}
+
 #define PARSE_ERR(_f, _a...)                 \
     do {                                     \
         printk( "ERROR: " _f "\n" , ## _a ); \
@@ -396,3 +414,13 @@ void serial_puts(int handle, const unsig
 
     spin_unlock_irqrestore(&uart->lock, flags);
 }
+
+unsigned char serial_getc(int handle)
+{
+    uart_t *uart = &com[handle & SERHND_IDX];
+
+    if ( handle == -1 )
+        return 0;
+
+    return __serial_getc(uart, handle);
+}
===================================================================
RCS file: include/xeno/serial.h,v
retrieving revision 1.1
diff -up -r1.1 include/xeno/serial.h
--- include/xeno/serial.h	2004/03/10 22:50:43	1.1
+++ include/xeno/serial.h	2004/03/10 23:14:15
@@ -36,4 +36,7 @@ void serial_putc(int handle, unsigned ch
 /* Transmit a NULL-terminated string via the specified COM port. */
 void serial_puts(int handle, const unsigned char *s);
 
+/* Receive a single character via the specified COM port. */
+unsigned char serial_getc(int handle);
+
 #endif /* __XEN_SERIAL_H__ */

[-- Attachment #3: Type: TEXT/PLAIN, Size: 2 bytes --]




[-- Attachment #4: sernet.c --]
[-- Type: TEXT/PLAIN, Size: 5595 bytes --]


/*  #define DUMP_HICONN */

#include <stdlib.h>
#include <stdarg.h>
#include <err.h>

#include <termios.h>
#include <unistd.h>

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/poll.h>
#include <signal.h>

#include <getopt.h>

#include <netdb.h>
#include <netinet/in.h>

#ifndef O_BINARY
#define O_BINARY 0
#endif

#ifdef __CYGWIN__
#define COMPORT "/dev/com3"
#else
#define COMPORT "/dev/ttyS0"
#endif

int stdin_needs_reset = 0;
struct termios stdtio;

void
sighandler(int arg)
{
	if (stdin_needs_reset && tcsetattr(STDIN_FILENO, TCSAFLUSH, &stdtio) < 0)
		err(arg, "tcsetattr failed");
	exit(arg);
}

void
err(int eval, const char *fmt, ...)
{
	va_list va;

	va_start(va, fmt);
	vwarn(fmt, va);
	va_end(va);
	sighandler(eval);
	exit(eval);		/* sigh */
}

int
listenport(int port)
{
	int fd, on;
	struct sockaddr_in sin;

	if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
		err(1, "socket");

	on = 1;
	if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) < 0)
		err(1, "setsockopt (SO_REUSEADDR)");

	memset(&sin, 0, sizeof(sin));
	sin.sin_family = AF_INET;
	sin.sin_port = htons(port);
	sin.sin_addr.s_addr = INADDR_ANY;
	if (bind(fd, (struct sockaddr *)&sin, sizeof(sin)) < 0)
		err(1, "bind: %d", port);

	if (listen(fd, 1) < 0)
		err(1, "listen");

	return fd;
}

int
main(int argc, char **argv)
{
	int fd, infd[2], outfd[2];
	unsigned char buf[129];
	struct termios tio;
	struct pollfd pfd[3];
	int binmode = 0;
	int doSend = -1;
	int delay = 500;
	char *sendString = NULL;
	int handshake = 0;
	int rate = B57600;
	int port = -1;
	int gdbport = -1;
	struct sockaddr_in peer;
	int peerlen;
	int escape = 0;

	for (;;) {
		int c;
		c = getopt (argc, argv, "g:p:");
		if (c == -1)
			break;
		switch (c) {
		case 'g':
			gdbport = atoi(optarg);
			break;
		case 'p':
			port = atoi(optarg);
			break;
		}
	}

	infd[0] = STDIN_FILENO;
	outfd[0] = STDOUT_FILENO;
	if (isatty(STDIN_FILENO)) {
		if (gdbport == -1) {
			if (port == -1)
				err(1, "port and gdbport not set with stdin a tty");
			gdbport = port + 1;
		}
		if (port != -1) {
			infd[0] = listenport(port);
			outfd[0] = -1;
		}
	} else {
		if (gdbport == -1)
			gdbport = port + 1;
		peerlen = sizeof(peer);
		if (getpeername(STDIN_FILENO, (struct sockaddr *)&peer, &peerlen) < 0)
			err(1, "getpeername");
		port = ntohs(peer.sin_port);
		infd[0] = STDIN_FILENO;
		outfd[0] = STDOUT_FILENO;
	}
	infd[1] = listenport(gdbport);
	outfd[1] = -1;
	fprintf(stderr, "listen on port %d/%d, fds %d/%d\n", port, gdbport, infd[0],
	    infd[1]);

	argc -= optind - 1;
	argv += optind - 1;

	fd = open (COMPORT, O_RDWR | O_NOCTTY | O_NONBLOCK | O_BINARY);
	if (fd < 0) {
		fprintf (stderr, "open failed");
		exit (1);
	}

	if (tcgetattr (fd, &tio) < 0)
		err(1, "tcgetattr failed");
	if (cfsetispeed (&tio, rate) < 0)
		err(1, "cfsetispeed failed");
	if (cfsetospeed (&tio, rate) < 0)
		err(1, "cfsetospeed failed");
	tio.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
	    |INLCR|IGNCR|ICRNL|IXON);
	tio.c_oflag &= ~OPOST;
	tio.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
	tio.c_cflag &= ~(CSIZE|PARENB);
	tio.c_cflag |= CS8;
	if (handshake) {
		tio.c_cflag|=CRTSCTS;
		tio.c_cflag|=CSTOPB;
	} else {
		tio.c_cflag&=~CRTSCTS;
		tio.c_cflag&=~CSTOPB;
	}
	if (tcsetattr (fd, TCSAFLUSH, &tio) < 0)
		err(1, "tcsetattr failed");

	if (isatty(infd[0])) {
		stdin_needs_reset = 1;
		signal (SIGINT, sighandler);

		if (tcgetattr (infd[0], &stdtio) < 0)
			err(1, "tcgetattr failed");
		if (tcgetattr (infd[0], &tio) < 0)
			err(1, "tcgetattr failed");
		tio.c_oflag &= ~OPOST;
		tio.c_lflag &= ~(ECHO|ECHONL|ICANON|/*ISIG|*/IEXTEN);
		tio.c_cflag &= ~(CSIZE|PARENB);
		tio.c_cflag |= CS8;
		if (tcsetattr (infd[0], TCSAFLUSH, &tio) < 0)
			err(1, "tcsetattr failed");
	}

	pfd[0].fd = fd;
	pfd[0].events = POLLIN;
	pfd[1].fd = infd[0];
	pfd[1].events = POLLIN;
	pfd[2].fd = infd[1];
	pfd[2].events = POLLIN;
	for (;;) {
		int c;
		while ((c = poll (pfd, 3, 15)) <= 0) {
			if (c < 0)
				err(1, "poll failed");
		}
		if ((pfd[0].revents & POLLIN) != 0) {
			c = read (fd, buf, 1);
			if (buf[0] & 0x80) {
				if (outfd[1] >= 0) {
					buf[0] &= 0x7f;
					write (outfd[1], buf, c);
#if DUMP_HICONN
					write (STDERR_FILENO, "[", 1);
					write (STDERR_FILENO, buf, c);
					write (STDERR_FILENO, "]", 1);
#endif
			}
			} else {
				if (outfd[0] >= 0)
					write (outfd[0], buf, c);
			}
		}
		if ((pfd[1].revents & POLLIN) != 0) {
			if (outfd[0] >= 0) {
				c = read (pfd[1].fd, buf, 1);
				if (c <= 0) {
					close(pfd[1].fd);
					pfd[1].fd = infd[0];
					outfd[0] = -1;
				} else {
					buf[0] &= 0x7f;
					if (escape == 0 && buf[0] == '~') {
						escape = 1;
						continue;
					} else if (escape == 1) {
						switch(buf[0]) {
						case '.':
							write (outfd[0], "\r\n", 2);
							sighandler(0);
							/* NOTREACHED */
							break;
						case '~':
							break;
						default:
							write (fd, "~", 1);
							break;
						}
					}
					if (buf[0] == '\n')
						escape = 0;
					else
						escape = 2;
					write (fd, buf, c);
				}
			} else {
				outfd[0] = accept(infd[0], NULL, NULL);
				pfd[1].fd = outfd[0];
			}
		}
		if ((pfd[2].revents & POLLIN) != 0) {
			if (outfd[1] >= 0) {
				c = read (pfd[2].fd, buf, 1);
				if (c <= 0) {
					close(pfd[2].fd);
					pfd[2].fd = infd[1];
					outfd[1] = -1;
				} else {
#ifdef DUMP_HICONN
					write (STDERR_FILENO, buf, c);
#endif
					buf[0] |= 0x80;
					write (fd, buf, c);
				}
			} else {
				outfd[1] = accept(infd[1], NULL, NULL);
				pfd[2].fd = outfd[1];
			}
		}
	}

	return 0;
}

[-- Attachment #5: Type: TEXT/PLAIN, Size: 39 bytes --]



-- 
Christian Limpach <chris@pin.lu>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: anybody using pdb?
  2004-03-11  0:10 anybody using pdb? Christian Limpach
@ 2004-03-11  8:28 ` Keir Fraser
  2004-03-11 17:21   ` Christian Limpach
  0 siblings, 1 reply; 6+ messages in thread
From: Keir Fraser @ 2004-03-11  8:28 UTC (permalink / raw)
  To: Christian Limpach; +Cc: xen-devel

> Hello!
> 
> I'd like to use pdb but it's not quite working as expected.
> 
> The 1st issue is that jumping to the debugger by pressing 'D' doesn't work
> because this leaves serial interrupts blocked.  Maybe this is only the
> case because I'm using lo/hi muxing but my guess is that it's not.  I've
> implemented a work around which seems to work:  if pdb is entered by the
> keypressed handler it will call a new serial_getc function if there's no
> input in the rx ring.  I'm not sure if this is also necessary when
> interacting with the debugger on a breakpoint or after a crash...

I've fixed this a better way, by enabling interrupts before calling
the pdb handler. Let me know if it still doesn't work.

> 2nd issue is that the debugger doesn't work when hitting a breakpoint (and
> possibly after a crash) which raises my question if anybody is actually
> using the pdb code which is in unstable ;-)

I don't think PDB is entered on a crash -- it currently appears only
to be hooked into the int3 and debug exception handlers.

 -- Keir


-------------------------------------------------------
This SF.Net email is sponsored by: IBM Linux Tutorials
Free Linux tutorial presented by Daniel Robbins, President and CEO of
GenToo technologies. Learn everything from fundamentals to system
administration.http://ads.osdn.com/?ad_id=1470&alloc_id=3638&op=click

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: anybody using pdb?
  2004-03-11  8:28 ` Keir Fraser
@ 2004-03-11 17:21   ` Christian Limpach
  2004-03-12  7:50     ` Keir Fraser
  2004-03-12 11:52     ` Keir Fraser
  0 siblings, 2 replies; 6+ messages in thread
From: Christian Limpach @ 2004-03-11 17:21 UTC (permalink / raw)
  To: Keir Fraser; +Cc: xen-devel

> I've fixed this a better way, by enabling interrupts before calling
> the pdb handler. Let me know if it still doesn't work.

No it doesn't work, at least not for the "jump to the debugger by pressing
D" case.  Maybe because you only enabled interrupts during traps but not
during interrupts?  AFAICT there's also some locking/flag setting which
might prevent further interrupts while the handler is still running (if I'm
looking at the right code, do_IRQ in xen/arch/i386/irq.c).

I considered enabling interrupts at first but I couldn't exclude re-entrance
issues.  Also I think that it's not the right thing to do in this case:  if
you're using the debugger on Xen, you don't want interrupts enabled.  I
think you'd actually want them explicitly disabled (as opposed to the
previous/current implicit disabling).

   christian



-------------------------------------------------------
This SF.Net email is sponsored by: IBM Linux Tutorials
Free Linux tutorial presented by Daniel Robbins, President and CEO of
GenToo technologies. Learn everything from fundamentals to system
administration.http://ads.osdn.com/?ad_id=1470&alloc_id=3638&op=click

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: anybody using pdb?
  2004-03-11 17:21   ` Christian Limpach
@ 2004-03-12  7:50     ` Keir Fraser
  2004-03-12 11:52     ` Keir Fraser
  1 sibling, 0 replies; 6+ messages in thread
From: Keir Fraser @ 2004-03-12  7:50 UTC (permalink / raw)
  To: Christian Limpach; +Cc: Keir Fraser, xen-devel

> > I've fixed this a better way, by enabling interrupts before calling
> > the pdb handler. Let me know if it still doesn't work.
> 
> No it doesn't work, at least not for the "jump to the debugger by pressing
> D" case.  Maybe because you only enabled interrupts during traps but not
> during interrupts?  AFAICT there's also some locking/flag setting which
> might prevent further interrupts while the handler is still running (if I'm
> looking at the right code, do_IRQ in xen/arch/i386/irq.c).
> 
> I considered enabling interrupts at first but I couldn't exclude re-entrance
> issues.  Also I think that it's not the right thing to do in this case:  if
> you're using the debugger on Xen, you don't want interrupts enabled.  I
> think you'd actually want them explicitly disabled (as opposed to the
> previous/current implicit disabling).

Hmmmm... maybe you're right. :-)

Certainly I've changed my mind about yesterday's fix. I'll back it out
and do something along the lines of what you posted in the first
place.

 -- Keir


-------------------------------------------------------
This SF.Net email is sponsored by: IBM Linux Tutorials
Free Linux tutorial presented by Daniel Robbins, President and CEO of
GenToo technologies. Learn everything from fundamentals to system
administration.http://ads.osdn.com/?ad_id=1470&alloc_id=3638&op=click

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: anybody using pdb?
  2004-03-11 17:21   ` Christian Limpach
  2004-03-12  7:50     ` Keir Fraser
@ 2004-03-12 11:52     ` Keir Fraser
  2004-03-12 15:10       ` Christian Limpach
  1 sibling, 1 reply; 6+ messages in thread
From: Keir Fraser @ 2004-03-12 11:52 UTC (permalink / raw)
  To: Christian Limpach; +Cc: Keir Fraser, xen-devel

> > I've fixed this a better way, by enabling interrupts before calling
> > the pdb handler. Let me know if it still doesn't work.
> 
> No it doesn't work, at least not for the "jump to the debugger by pressing
> D" case.  Maybe because you only enabled interrupts during traps but not
> during interrupts?  AFAICT there's also some locking/flag setting which
> might prevent further interrupts while the handler is still running (if I'm
> looking at the right code, do_IRQ in xen/arch/i386/irq.c).
> 
> I considered enabling interrupts at first but I couldn't exclude re-entrance
> issues.  Also I think that it's not the right thing to do in this case:  if
> you're using the debugger on Xen, you don't want interrupts enabled.  I
> think you'd actually want them explicitly disabled (as opposed to the
> previous/current implicit disabling).
> 
>    christian
> 

Okay, I checked in a fix somewhat like the one you initially
proposed. Fancy giving it another spin? :-)

 -- Keir


-------------------------------------------------------
This SF.Net email is sponsored by: IBM Linux Tutorials
Free Linux tutorial presented by Daniel Robbins, President and CEO of
GenToo technologies. Learn everything from fundamentals to system
administration.http://ads.osdn.com/?ad_id=1470&alloc_id=3638&op=click

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: anybody using pdb?
  2004-03-12 11:52     ` Keir Fraser
@ 2004-03-12 15:10       ` Christian Limpach
  0 siblings, 0 replies; 6+ messages in thread
From: Christian Limpach @ 2004-03-12 15:10 UTC (permalink / raw)
  To: Keir Fraser; +Cc: xen-devel

> Okay, I checked in a fix somewhat like the one you initially
> proposed. Fancy giving it another spin? :-)

Ok, this works.  Thanks!

And breakpoints now work occasionally...  I think the problem is that my
test machine is 2-CPU SMP:
(from a log of the 'wire' between gdb and Xen, Xen->gdb is in [], everything
else is gdb->Xen)
$Mfc510390,1:cc#a5[+][$][O][K][#][9][$][S][a][0]
Here gdb sets the breakpoint by writing 0xcc to the breakpoint address.
Xen then would acknowledge this by replying with OK by sending "+$OK#9a" but
it doesn't get to entirely send the reply since I guess the breakpoint is
hit on the other CPU? (the breakpoint is on __enter_scheduler btw)

The log should look like this:
$Mfc510390,1:cc#a5[+][$][O][K][#][9][a]+$Hc0#db[+][$][O][K][#][9][a]+$C0a#d4
[+][$][S][0][5][#][b][8]+
Here the reply works and gdb sends commands Hc0 and C0a to continue
execution and only then Xen hits the breakpoint and sends $S05#b8 which gdb
then acknowledges with a +...

I guess we'd have to IPI the other CPUs when we hit a breakpoint?

    christian



-------------------------------------------------------
This SF.Net email is sponsored by: IBM Linux Tutorials
Free Linux tutorial presented by Daniel Robbins, President and CEO of
GenToo technologies. Learn everything from fundamentals to system
administration.http://ads.osdn.com/?ad_id=1470&alloc_id=3638&op=click

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2004-03-12 15:10 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-03-11  0:10 anybody using pdb? Christian Limpach
2004-03-11  8:28 ` Keir Fraser
2004-03-11 17:21   ` Christian Limpach
2004-03-12  7:50     ` Keir Fraser
2004-03-12 11:52     ` Keir Fraser
2004-03-12 15:10       ` Christian Limpach

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.