NetBSD Problem Report #16407

Received: (qmail 27319 invoked from network); 19 Apr 2002 05:35:17 -0000
Message-Id: <200204190535.g3J5ZGk25120@nekozame.a.grotto.jp>
Date: Fri, 19 Apr 2002 14:35:16 +0900 (JST)
From: bsh@grotto.jp
Reply-To: bsh@grotto.jp
To: gnats-bugs@gnats.netbsd.org
Subject: remote kgdb `next' command doesn't work in some situation.
X-Send-Pr-Version: 3.95

>Number:         16407
>Category:       kern
>Synopsis:       remote kgdb `next' command doesn't work in some situation.
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Fri Apr 19 05:36:00 +0000 2002
>Closed-Date:    
>Last-Modified:  Fri Nov 06 17:08:48 +0000 2020
>Originator:     Hiroyuki Bessho
>Release:        NetBSD 1.5ZC
>Organization:
	Genetec corp.
>Environment:
System: NetBSD lubbock1 1.5ZC NetBSD 1.5ZC (LUBBOCK) #0: Thu Apr 18 07:00:58 JST 2002     bsh@sawara:/usr/src/sys/arch/evbarm/compile/LUBBOCK evbarm
Architecture: arm
Machine: evbarm
com.c: $NetBSD: com.c,v 1.194 2002/03/17 19:40:57 atatat Exp $
>Description:

Gdb's `next' command lets the program run until it reaches the next
statement. If you issue `next' command when the insn at current
position is a function call, gdb does:

   1. set temporary breakpoint at the first insn of the function.
   2. let the CPU run.  It hits breakpoint immediately.
   3. remove the breakpoint, then sets new breakpoint at the next
      statement of the original position.
   4. let the CPU run again. It runs through the function,
      returns from the function, then hits breakpoint.

So, if the current statement is call to splserial(), gdb sets
breakpoint in splserial() to execute `next' command. 

On hitting breakpoints, kgdb stub calls kgdb_putc() and kgdb_getc() to
communicate with remote gdb.  Current implementaion of
kgdb_{put,get}c() in com.c call splserial() and splx(). If a
breakpoint is set in splserial() for `next' command, kgdb stub calls
kgdb_{put,get}c(), and hits the breakpoint again.  Thus, stub can't
communicate with remote gdb in such situation.

By the same reason, you can't set breakpoints in splserial(), splx(),
or subroutines that are called by them.

Note that this doesn't cause any problem when splfoo() is defined as
an inline function or macro, like in i386 port.

>How-To-Repeat:
Start remote kgdb session with NetBSD kernel, and issue `next' command
at the statement that calls splserial().

>Fix:
kgdb_{get,put}c should not call splserial().  Attached patch seems to
fix the problem.  The patch consists of three changes:

   1. move splserial()/splx() calls to comcngetc() and comcnputc() from 
      com_common_getc() and com_common_putc().

   2. Also move com_readahead[] stuff from com_common_{get,put}c, since it is
      for a console port.

   3. disable interrupts in kgdb_{put,get}c() by tweaking hardware registers
      instead of splserial().

I've tested remote kgdb with modified com driver on NetBSD/i386 and
NetBSD/evbarm, and console debugger on i386.


--- com.c.ORIG	Mon Apr 15 15:46:15 2002
+++ com.c	Wed Apr 17 15:46:46 2002
@@ -2275,22 +2275,8 @@
 	bus_space_tag_t iot;
 	bus_space_handle_t ioh;
 {
-	int s = splserial();
 	u_char stat, c;

-	/* got a character from reading things earlier */
-	if (com_readaheadcount > 0) {
-		int i;
-
-		c = com_readahead[0];
-		for (i = 1; i < com_readaheadcount; i++) {
-			com_readahead[i-1] = com_readahead[i];
-		}
-		com_readaheadcount--;
-		splx(s);
-		return (c);
-	}
-
 	/* block until a character becomes available */
 	while (!ISSET(stat = bus_space_read_1(iot, ioh, com_lsr), LSR_RXRDY))
 		;
@@ -2305,7 +2291,6 @@
 #endif
 			cn_check_magic(dev, c, com_cnm_state);
 	}
-	splx(s);
 	return (c);
 }

@@ -2316,19 +2301,8 @@
 	bus_space_handle_t ioh;
 	int c;
 {
-	int s = splserial();
 	int timo;

-	int cin, stat;
-	if (com_readaheadcount < MAX_READAHEAD 
-	     && ISSET(stat = bus_space_read_1(iot, ioh, com_lsr), LSR_RXRDY)) {
-		int cn_trapped = 0;
-		cin = bus_space_read_1(iot, ioh, com_data);
-		stat = bus_space_read_1(iot, ioh, com_iir);
-		cn_check_magic(dev, cin, com_cnm_state);
-		com_readahead[com_readaheadcount++] = cin;
-	}
-
 	/* wait for any pending transmission to finish */
 	timo = 150000;
 	while (!ISSET(bus_space_read_1(iot, ioh, com_lsr), LSR_TXRDY) && --timo)
@@ -2342,7 +2316,6 @@
 	while (!ISSET(bus_space_read_1(iot, ioh, com_lsr), LSR_TXRDY) && --timo)
 		continue;

-	splx(s);
 }

 /*
@@ -2415,7 +2388,24 @@
 comcngetc(dev)
 	dev_t dev;
 {
-	return (com_common_getc(dev, comconstag, comconsioh));
+	int s = splserial();
+	int c;
+
+	/* got a character from reading things earlier */
+	if (com_readaheadcount > 0) {
+		int i;
+
+		c = com_readahead[0];
+		for (i = 1; i < com_readaheadcount; i++) {
+			com_readahead[i-1] = com_readahead[i];
+		}
+		com_readaheadcount--;
+	}
+	else {
+		c = com_common_getc(dev, comconstag, comconsioh);
+	}
+	splx(s);
+	return c;
 }

 /*
@@ -2426,7 +2416,21 @@
 	dev_t dev;
 	int c;
 {
+	int s = splserial();
+	int cin, stat;
+
+	if (com_readaheadcount < MAX_READAHEAD 
+	     && ISSET(stat = bus_space_read_1(comconstag, comconsioh, com_lsr),
+		      LSR_RXRDY)) {
+		int cn_trapped = 0;
+		cin = bus_space_read_1(comconstag, comconsioh, com_data);
+		stat = bus_space_read_1(comconstag, comconsioh, com_iir);
+		cn_check_magic(dev, cin, com_cnm_state);
+		com_readahead[com_readaheadcount++] = cin;
+	}
+
 	com_common_putc(dev, comconstag, comconsioh, c);
+	splx(s);
 }

 void
@@ -2475,7 +2479,14 @@
 com_kgdb_getc(arg)
 	void *arg;
 {
-	return (com_common_getc(NODEV, com_kgdb_iot, com_kgdb_ioh));
+	int c;
+
+	bus_space_write_1( com_kgdb_iot, com_kgdb_ioh,
+			 com_ier, 0 );
+	c = com_common_getc(NODEV, com_kgdb_iot, com_kgdb_ioh);
+	bus_space_write_1( com_kgdb_iot, com_kgdb_ioh,
+			 com_ier,  IER_ERXRDY );
+	return c;
 }

 /* ARGSUSED */
@@ -2484,7 +2495,11 @@
 	void *arg;
 	int c;
 {
+	bus_space_write_1( com_kgdb_iot, com_kgdb_ioh,
+			 com_ier, 0 );
 	com_common_putc(NODEV, com_kgdb_iot, com_kgdb_ioh, c);
+	bus_space_write_1( com_kgdb_iot, com_kgdb_ioh,
+			 com_ier,  IER_ERXRDY );
 }
 #endif /* KGDB */

>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: kern-bug-people->kamil
Responsible-Changed-By: kamil@NetBSD.org
Responsible-Changed-When: Sat, 07 Oct 2017 15:49:31 +0200
Responsible-Changed-Why:
Take.


Responsible-Changed-From-To: kamil->kern-bug-people
Responsible-Changed-By: kamil@NetBSD.org
Responsible-Changed-When: Fri, 06 Nov 2020 18:08:48 +0100
Responsible-Changed-Why:
Reassign to kern-bug-people.


>Unformatted:

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.46 2020/01/03 16:35:01 leot Exp $
$NetBSD: gnats_config.sh,v 1.9 2014/08/02 14:16:04 spz Exp $
Copyright © 1994-2020 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.