All of lore.kernel.org
 help / color / mirror / Atom feed
From: Christian Limpach <chris@pin.lu>
To: xen-devel@lists.sourceforge.net
Subject: anybody using pdb?
Date: Thu, 11 Mar 2004 01:10:07 +0100	[thread overview]
Message-ID: <200403110010.i2B0ACO27214@mail.Pin.LU> (raw)

[-- 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>

             reply	other threads:[~2004-03-11  0:10 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-03-11  0:10 Christian Limpach [this message]
2004-03-11  8:28 ` anybody using pdb? 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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200403110010.i2B0ACO27214@mail.Pin.LU \
    --to=chris@pin.lu \
    --cc=xen-devel@lists.sourceforge.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.