[gnu.gdb.bug] volatle is broken

kent@SUNDC.EAST.SUN.COM (Kent Hauser) (09/27/89)

Configuration:	compiler: gcc 1.35
		host: Sun 3/60, SunOS 3.5
		target: 68000 standalone system, using a
		slightly modified `config.gdb sun2' arrangement
	
Description: gdb doesn't honor volatile declaration

Discussion:

Three bugs in gdb (and/or gcc) are identified in the script below.  As
there seems to be little documentation on `stabs', I do not know if
the `volatile' declaration is making it out of gcc.  However, `gdb'
doesn't understand the `C' keyword `volatile'.  Also, `gdb' reads
the `volatile' data before it writes it. Finally, instead of writing
out a `char', it writes out a `long'.

Needless to say, this is no good at all for debugging `volatile' things
like hardware control registers.

As I do not understand the internals of `gdb', I can not even begin
to make a suggestion as to the proper solutions to these problems.
However, I do have a suggestion for a hack:

*begin hack*
If the address is greater than `STACK_END_ADDR' (defined for kdb),
then don't cache & honor the size (char, short, long) explicitly.
In other words, treat every reference above `STACK_END_ADDR' as
automatically volatile.
*end hack*

Script:

Consider the following source file & assembly output (including stabs)

====
/*
 * this to test volatile
 */

volatile char *led = 0x180001;

set_led (i)
{
  *led = i;
}
====
%gcc -g -O -S -mc68000 volatile.c
volatile.c:5: warning: initialization of pointer from integer lacks a cast
%cat volatile.s
#NO_APP
gcc_compiled.:
	.stabs "b.c",100,0,0,Ltext
Ltext:
.stabs "int:t1=r1;-2147483648;2147483647;",128,0,0,0
.stabs "char:t2=r2;0;127;",128,0,0,0
.stabs "long int:t3=r1;-2147483648;2147483647;",128,0,0,0
.stabs "unsigned int:t4=r1;0;-1;",128,0,0,0
.stabs "long unsigned int:t5=r1;0;-1;",128,0,0,0
.stabs "short int:t6=r1;-32768;32767;",128,0,0,0
.stabs "long long int:t7=r1;0;-1;",128,0,0,0
.stabs "short unsigned int:t8=r1;0;65535;",128,0,0,0
.stabs "long long unsigned int:t9=r1;0;-1;",128,0,0,0
.stabs "signed char:t10=r1;-128;127;",128,0,0,0
.stabs "unsigned char:t11=r1;0;255;",128,0,0,0
.stabs "float:t12=r1;4;0;",128,0,0,0
.stabs "double:t13=r1;8;0;",128,0,0,0
.stabs "long double:t14=r1;8;0;",128,0,0,0
.stabs "void:t15=15",128,0,0,0
.stabs "led:G16=*2",32,0,0,0
.globl _led
.data
	.even
_led:
	.long 1572865
.text
	.even
.globl _set_led
_set_led:
	.stabd 68,0,8
	link a6,#0
	.stabd 68,0,9
	movel _led,a0
	moveb a6@(11),d0
	moveb d0,a0@
	.stabd 68,0,10
	unlk a6
	rts
.stabs "set_led:F1",36,0,0,_set_led
.stabs "i:p1",160,0,0,8
======

GDB session:

This is the result of running gdb-remote under plain gdb.  Breakpoints are
set in `remote.c' to trace buffer messages.

The lines that start with a `#' are my comments

Current directory is /usr/src/gnu/gdb/
GDB 3.2, Copyright (C) 1988 Free Software Foundation, Inc.
There is ABSOLUTELY NO WARRANTY for GDB; type "info warranty" for details.
GDB is free software and you are welcome to distribute copies of it
 under certain conditions; type "info copying" to see the conditions.
Reading symbol data from /usr/src/gnu/gdb/gdb-tfd...done.
Setting up the environment for debugging gdb.
Reading in symbols for main.c...done.
Reading in symbols for blockframe.c...done.
Reading in symbols for findvar.c...done.
Reading in symbols for valops.c...done.
Reading in symbols for infrun.c...done.
Reading in symbols for remote.c...done.
Reading in symbols for utils.c...done.
Breakpoint 1 at 0x273f6: file utils.c, line 274.
Breakpoint 2 at 0x34f0: file main.c, line 964.
Type "help" for a list of commands.

# these breakpoints are in function `remote_send' right before
# the call to `putpkt' and right after the call to `getpkt'

(top-gdb) Breakpoint 3 at 0x25c9c: file remote.c, line 458.
(top-gdb) Breakpoint 4 at 0x25cb4: file remote.c, line 460.
(top-gdb) r -fullname -cd /usr/kent/src/m68k otest
Starting program: /usr/src/gnu/gdb/gdb-tfd -fullname -cd /usr/kent/src/m68k otest
GDB 3.2, Copyright (C) 1988 Free Software Foundation, Inc.
There is ABSOLUTELY NO WARRANTY for GDB; type "info warranty" for details.
GDB is free software and you are welcome to distribute copies of it
 under certain conditions; type "info copying" to see the conditions.
Reading symbol data from /usr/kent/src/m68k/otest...done.
Type "help" for a list of commands.

# start the remote session

(gdb) attach /dev/ttyp5
Attaching remote machine
Remote debugging using /dev/ttyp5

# read remote registers

Bpt 3, remote_send (buf=(char *) 0xefffa1c "g") (remote.c line 458)
(top-gdb) 
(top-gdb) c
Continuing.

Bpt 4, remote_send (buf=(char *) 0xefffa1c "000000a0000414740000002f0000000370b27c2bff9e75fd47be7e856ef7337700041474000401401d2c3e4db9ff3fff00000ebc0004147800047fe800047fe80000270000000ebc") (remote.c line 461)
(top-gdb) 
Continuing.

Program received signal 5, Trace/BPT trap
Reading in symbols for remcom.c...done.
breakpoint () (remcom.c line 909)

# now play with the volatile variable

(gdb) set *(volatile char *)led=1
No symbol "volatile" in current context.

# bug #1: `gdb' need to learn the volatile keyword!

(gdb) set *led=1
Reading in symbols for volatile.c...done.

# this I/O is to read the value of `led'

Bpt 3, remote_send (buf=(char *) 0xefff8f0 "m416a0,10") (remote.c line 458)
(top-gdb) 
Continuing.

Bpt 4, remote_send (buf=(char *) 0xefff8f0 "000046eb889b777f001800013aa90000") (remote.c line 461)
(top-gdb) 
Continuing.

# bug #2:  `*led' is being *read* to fill the data cache!

Bpt 3, remote_send (buf=(char *) 0xefff970 "m180000,10") (remote.c line 458)
(top-gdb) 
Continuing.


Bpt 4, remote_send (buf=(char *) 0xefff970 "fffbfffbfffbfffbfffbfffbfffbfffb") (remote.c line 461)
(top-gdb) 
Continuing.

# bug #3: a `long', not a `char' is being written at `*led'

Bpt 3, remote_send (buf=(char *) 0xefff9ac "M180000,4:ff01fffb") (remote.c line 458)
(top-gdb) 
Continuing.

Bpt 4, remote_send (buf=(char *) 0xefff9ac "OK") (remote.c line 461)
(top-gdb) 
Continuing.
(gdb) quit
The program is running.  Quit anyway? (y or n) y

Program exited normally.
(top-gdb) quit

Inferior Gdb finished

================

Kent Hauser			UUCP: {uunet!cucstud, sun!sundc}!tfd!kent
Twenty-First Designs		INET: sundc!tfd!kent@sun.com

kingdon@AI.MIT.EDU (Jim Kingdon) (09/28/89)

I have disabled the remote caching stuff completely to fix this
problem.  The other person who noticed this bug didn't notice much of
a performance hit when he did this, so I don't see any reason to worry
about the lost caching.  Thanks for your bug report.

    volatile char *led = 0x180001;

This is unreleated to the GDB problem, since the remote debugging
cache didn't check for "volatile", but I'm not sure this is the right
declaration.  Doesn't this say "volatile pointer to character" rather
than "pointer to volatile character"?  Perhaps you mean "char volatile
* led" (but don't quote me on that; I've never fully figured out type
qualifiers in C).