Bug 16606 - While setting temporary breakpoint on AVR8, GDB made access to out of range program memory.
Summary: While setting temporary breakpoint on AVR8, GDB made access to out of range p...
Status: NEW
Alias: None
Product: gdb
Classification: Unclassified
Component: breakpoints (show other bugs)
Version: 7.7
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-02-19 10:23 UTC by vidarl
Modified: 2014-03-03 09:01 UTC (History)
1 user (show)

See Also:
Host:
Target: Avr8
Build: GNU gdb (GDB) 7.7.50.20140214-cvs
Last reconfirmed:


Attachments
Source code and ELF file for example program. (2.24 KB, application/x-zip-compressed)
2014-02-19 10:23 UTC, vidarl
Details

Note You need to log in before you can comment on or make changes to this bug.
Description vidarl 2014-02-19 10:23:32 UTC
Created attachment 7428 [details]
Source code and ELF file for example program.

When debugging an AVR8 program and setting breakpoint at a specified address, the breakpoint is set on a different address typically (address & 0x800000) which is in the data segment (OFFSET_DATA is 0x800000). This was seen first for temporary breakpoints when running debugging with GDB in Atmel Studio 6.2 beta, it was also reproduced when debugging AVR8 (ATMega2560) in GDB through gdbproxy (with simulator model libATmega256.dll). The log below shows this problem resulting in message:
  Warning:
  Cannot insert breakpoint 2.
  Cannot access memory at address 0x80010e

It also shows a problem when stepping out of multiply to main resulting in message:
  Warning:
  Cannot insert breakpoint 0.
  Cannot access memory at address 0x1f00000

Log of GDB v7.7.50 session (Feb. 14, 2014 version):
----------------------------------------------------------------
$ ../../../binutils-gdb-build-avr-20140214/gdb/gdb
GNU gdb (GDB) 7.7.50.20140214-cvs
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=i686-pc-mingw32 --target=avr".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word".
(gdb) target remote :20349
:20349: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection f
ailed because connected host has failed to respond.
(gdb) target remote :50349
Remote debugging using :50349
warning: limiting remote suggested packet size (131104 bytes) to 16384
0x00000000 in ?? ()
(gdb) load ATMega2560-simple-program
ATMega2560-simple-program: No such file or directory.
(gdb) load ATMega2560-simple-program.elf
Loading section .text, size 0x152 lma 0x0
Start address 0x0, load size 338
Transfer rate: 165 KB/sec, 338 bytes/write.
(gdb) file ATMega2560-simple-program.elf
A program is being debugged already.
Are you sure you want to change the file? (y or n) y
Reading symbols from ATMega2560-simple-program.elf...done.
(gdb) monitor reset
Performing Power-on reset -  Reset OK
(gdb) tbreak main
Temporary breakpoint 1 at 0x13e: file .././ATMega2560-simple-program.c, line 22.
(gdb) cont
Continuing.
Temporary breakpoint 1, main () at .././ATMega2560-simple-program.c:22
22                      int a = multiply(2, 3);
(gdb) break *0x10e
Breakpoint 2 at 0x80010e
(gdb) info break
Num     Type           Disp Enb Address    What
2       breakpoint     keep y   0x0080010e
(gdb) info line 14
Line 14 of ".././ATMega2560-simple-program.c" starts at address 0x10e <multiply+20> and ends at 0x124 <multiply+42>.
(gdb) step
Warning:
Cannot insert breakpoint 2.
Cannot access memory at address 0x80010e
(gdb) delete break
Delete all breakpoints? (y or n) y
(gdb) step
multiply (a=2, b=3) at .././ATMega2560-simple-program.c:14
14              return a * b;
(gdb) bt
#0  multiply (a=2, b=3) at .././ATMega2560-simple-program.c:14
#1  0x01f00000 in ?? ()
(gdb) where
#0  multiply (a=2, b=3) at .././ATMega2560-simple-program.c:14
#1  0x01f00000 in ?? ()
(gdb) finish
Run till exit from #0  multiply (a=2, b=3) at .././ATMega2560-simple-program.c:14
Warning:
Cannot insert breakpoint 0.
Cannot access memory at address 0x1f00000
(gdb) step
15      }
(gdb) step
main () at .././ATMega2560-simple-program.c:23
23          }
(gdb) step
22                      int a = multiply(2, 3);
(gdb)
Comment 1 Jeremy Bennett 2014-03-03 09:01:13 UTC
The problem is with the function avr_integer_to_address which is called whenever a command is given a literal constant that must be interpreted as an address, for example

  breakpoint *0x10e
  disassemble 0x10e

The different address spaces in AVR are indicated wthin GDB by setting high order bits as follows

  0x00000000 - Flash (code)
  0x00800000 - SRAM
  0x00810000 - EEPROM

So even though AVR has 3 address spaces, all starting at logical address zero, they can be represented to GDB as a single address space (see https://sourceware.org/gdb/wiki/Internals%20Pointers-and-Addresses for more on this).

avr_integer_to_addressalways converts the value to an address in the SRAM area, which is why you see the value as 0x8010e. Clearly in the case of a breakpoint we would like it be an address in the Flash area.

It is not sufficient to change the function to always return an address in flash, since it is also used under circumstances where the constant is a pointer to data. 

avr_integer_to_address is passed a type, but it is it the inferred type of the constant, which in both the examples above is integer, so this does not help with the problem. To fix this is, the relevant commands need to be able to indicate what sort of address they are expecting (disas for example would expect a code address).

Some of this can be done within the existing architectural functions. For example we can define AVR specific functions to set breakpoints, which ensure the address is in code space (which will solve your immediate problem). I'll provide a patch for this shortly.

This doesn't work as a generic solution. For example.

  x/i 0x10e

Presumably refers to code space. But

  x/x 0x10e

probably refers to data space, unless the user was trying to look at the encoding of an instruction in code space. And even if it is in data space, does it refer to SRAM or EEPROM?

I'm working on some changes to GDB which will give the user greater control over multiple-address space architectures.