<error reading variable> when trying to follow the variable with watchpoint - c

When I try to follow a program for debugging purposes, my GDB fails to show how variable changes.
I tried to install different versions of GDB, but still got the same issue.
GNU gdb (GDB) 7.6.1
Copyright (C) 2013 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 "mingw32".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from C:\Users\china\Documents\LU\SCC.150\practicals\week20\mystrtest.exe...done.
(gdb) break main
Breakpoint 1 at 0x401602: file mystrtest.c, line 26.
(gdb) run
Starting program: C:\Users\china\Documents\LU\SCC.150\practicals\week20/mystrtest.exe
[New Thread 21152.0x4fa8]
[New Thread 21152.0x5670]
Breakpoint 1, main () at mystrtest.c:26
26 char test_string_1[] = "hello world!";
(gdb) watch test_string_1
Hardware watchpoint 2: test_string_1
(gdb) cont
Continuing.
Hardware watchpoint 2: test_string_1
Old value = <error reading variable>
New value = <error reading variable>
0x00401612 in main () at mystrtest.c:26
26 char test_string_1[] = "hello world!";
(gdb)
I wanted to see the old and new states of the variables, instead of getting an error.

Related

What's the diffrence between __libc_start_main and __libc_start_call_main?

I came to know about the __libc_start_main function. I have been thinking that __libc_start_main call the main function like this, but when I checked ret of main function of my own program, it is the address of __libc_start_call_main. What's the diffrence between __libc_start_main and __libc_start_call_main?
source code of my program, test.c
#include <stdio.h>
int main(void)
{
puts("Sunghyeon Lee");
}
gdb output:
──(kali㉿kali)-[~]
└─$ gdb test
GNU gdb (Debian 12.1-3) 12.1
Copyright (C) 2022 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 "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://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"...
Reading symbols from test...
(No debugging symbols found in test)
(gdb) b *main
Breakpoint 1 at 0x1139
(gdb) r
Starting program: /home/kali/test
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Breakpoint 1, 0x0000555555555139 in main ()
(gdb) x/a $rsp
0x7fffffffdec8: 0x7ffff7dd920a <__libc_start_call_main+122>
Thank you for your help!
I have searched about the diffrence between __libc_start_main and __ibc_start_call_main, I have never found the explanation about it.
I have never found the explanation about it.
Take a look at the commit which created __libc_start_call_main.
Effectively a chunk of __libc_start_main was split out into a separate routine.

gdb can not set breakpoint at correct position

I am a starter to C and am trying to use gdb to debug a simple program:
#include <stdio.h>
int main(int argc, char *argv[]) {
int i;
i = 2;
return 0;
}
The problem is when I use gdb b main, it did not work correctly:
PS F:\try> gcc -g -o try try.c
PS F:\try> gdb try
GNU gdb (GDB) 8.1
Copyright (C) 2018 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 "x86_64-w64-mingw32".
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"...
Reading symbols from try...done.
(gdb) b main
Breakpoint 1 at 0x401564: file try.c, line 4.
The breakpoint is set at line 4 however I suppose it should be set at the start of main().
Even if I set this manually, when I run the program the breakpoint won't get hit:
PS F:\try> gcc -g -o try try.c
PS F:\try> gdb try
GNU gdb (GDB) 8.1
Copyright (C) 2018 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 "x86_64-w64-mingw32".
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"...
Reading symbols from try...done.
(gdb) b 2
Breakpoint 1 at 0x401564: file try.c, line 2.
(gdb) run
Starting program: F:\try\try.exe
[New Thread 11464.0xbf8]
[New Thread 11464.0x508]
Thread 1 hit Breakpoint 1, main (argc=1, argv=0x181490) at try.c:4
4 i = 2;
As shown above I set a breakpoint at line 2 but it ran through line 4. How can I fix this?
Breakpoints can only be set on statements that do something. Declarations don't do anything, so they're skipped over, and the breakpoint is put on the first executable statement, which is
i = 2;

Conditional data watchpoint doesn't work in ARM GDB

My intent is to be able to catch when a global variable has some exact value. GDB has data watchpoints according to which this can be implemented.
Consider this simple program written for x86 Linux:
int myVar = 0;
void debug_watchpoints() {
for(int i=0; i < 2000; i++) {
myVar++;
}
}
int main() {
debug_watchpoints();
return 0;
}
Compiling the program with
gcc -o main -ggdb3 -Og main.c
And starting debugging with GDB:
max#PC-LT-23:~/stackoverflow$ gdb ./main
GNU gdb (Ubuntu 8.3-0ubuntu1) 8.3
Copyright (C) 2019 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 "x86_64-linux-gnu".
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"...
Reading symbols from ./main...
(gdb) b main
Breakpoint 1 at 0x1146: file main.c, line 9.
(gdb) start
Temporary breakpoint 2 at 0x1146: file main.c, line 9.
Starting program: /home/max/stackoverflow/main
Breakpoint 1, main () at main.c:9
9 int main() {
(gdb) watch myVar if myVar==1337
Hardware watchpoint 3: myVar
(gdb) continue
Continuing.
Hardware watchpoint 3: myVar
Old value = 1336
New value = 1337
debug_watchpoints () at main.c:4
4 for(int i=0; i < 2000; i++) {
(gdb)
As you can see it halted the program at exactly the point in time when the variable was set to 1337.
Consider the exact same program, compiled with arm-none-eabi-gcc for a STM32L476RG microcontroller which has a Cortex-M4F core. The used IDE here is System Workbench for STM32 (aka Eclipse) with a project generated by STM32CubeMX.
Now launching openocd gives
Open On-Chip Debugger 0.10.0+dev-00021-g524e8c8 (2019-04-12-08:33)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
srst_only separate srst_nogate srst_open_drain connect_assert_srst
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
padded zone erase set to 1
adapter speed: 8000 kHz
adapter_nsrst_delay: 100
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : clock speed 8000 kHz
Info : STLINK v2.1 JTAG v34 API v2 M25 VID 0x0483 PID 0x374B
Info : using stlink api v2
Info : Target voltage: 0.011074
Error: target voltage may be too low for reliable debugging
Info : Unable to match requested speed 8000 kHz, using 4000 kHz
Info : Stlink adapter speed set to 4000 kHz
Info : STM32L476RGTx.cpu: hardware has 6 breakpoints, 4 watchpoints
Info : Listening on port 3333 for gdb connections
Info : accepting 'gdb' connection on tcp/3333
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x08001340 msp: 0x20018000
A breakpoint is set in the main function and then the watchpoint is setup exactly like before. Also, a breakpoint is is set after the execution of the debug_watchpoints() function.
GNU gdb (GNU Tools for Arm Embedded Processors 9-2019-q4-major) 8.3.0.20190709-git
Copyright (C) 2019 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=x86_64-linux-gnu --target=arm-none-eabi".
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) Reset_Handler () at ../startup/startup_stm32l476xx.s:63
63 ldr sp, =_estack /* Set stack pointer */
Temporary breakpoint 3, main () at ../Src/main.c:65
65 {
(gdb) watch myVar if myVar==1337
Hardware watchpoint 4: myVar
(gdb) info breakpoints
Num Type Disp Enb Address What
2 breakpoint keep y 0x08000f46 in main at ../Src/main.c:70
4 hw watchpoint keep y myVar
stop only if myVar==1337
(gdb)
When continuing the program, it now stops at every modification of the variable with a SIGTRAP, regardless of whether the condition was met or not.
Program received signal SIGTRAP, Trace/breakpoint trap.
0x08000ec2 in debug_watchpoints () at ../Src/main.c:54
54 for(int i=0; i < 2000; i++) {
(gdb) continue
Continuing.
Program received signal SIGTRAP, Trace/breakpoint trap.
0x08000ec2 in debug_watchpoints () at ../Src/main.c:54
54 for(int i=0; i < 2000; i++) {
(gdb) continue
Continuing.
Program received signal SIGTRAP, Trace/breakpoint trap.
0x08000ec2 in debug_watchpoints () at ../Src/main.c:54
54 for(int i=0; i < 2000; i++) {
(gdb) info breakpoint
Num Type Disp Enb Address What
2 breakpoint keep y 0x08000f46 in main at ../Src/main.c:70
4 hw watchpoint keep y myVar
stop only if myVar==1337
(gdb) print myVar
$2 = 3
I can continue for as many times as I want, it just breaks each and every time the variable is changed.
In my scenario of "debugging a memory corruption on the stack", I really need GDB to evaluate the condition correctly, otherwise the program stops a thousand times or more (every time a variable which happens to be at this memory location is changed) and not at only the specific time a specific value is written into it to catch a bug.
Why does arm-none-eabi-gdb differ here in its behavior from normal gdb? Could the error lie in the Cortex-M4 hardware debugging capabilities, arm-none-eabi-gdb, or openocd as the GDB server?
As said, there's no working implementation in openocd, the debugger bridge you are using.
You can set by sw. Here a small snippet. COMP2, FUNCTION2, COMP1 and FUNCTION1 are DWT registers. Please note that you need to use two comparators linked together. Not all Cortex-m implementations support these features and not all comparators are linkable, it depends on your silicon. Also it seems that the capture is asynchonous. Generally my PC stops a few istruction after the trigger.
DWT->COMP2 = <address to compare>;
DWT->FUNCTION2 = 0;
DWT->COMP1 = <word to compare>;
DWT->FUNCTION1 = 0x20B06;
None of the software I know does it out of the box. When |I use the DWT usually I set it in my software. I have not found any way to program it via any variant of gdb (except manual setting the registers - but it is too annoying)

GDB quits when running the 'finish' command

I downloaded mingw-w64 so I can work on writing programs and debugging them from my home laptop, but for whatever reason, when ever I'm debugging a program with gdb and I wish to exit function using 'finish' command, gdb simply runs until it returns from function and simply exits and I return to the shell's prompt. I have no idea what is causing this bug, and it is especially annoying and make debugging very hard because it forces me to go through every line in a function before exiting (God forbids there's a loop). Has someone encountered this bug before? Is there a solution?
PS C:\Users\gamef\OneDrive\Desktop\CPE453\program4_tinyfs> gdb .\a.exe
GNU gdb (GDB) 8.1
Copyright (C) 2018 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 "x86_64-w64-mingw32".
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"...
Reading symbols from .\a.exe...done.
(gdb) br writeData
Breakpoint 1 at 0x402e44: file TinyFS.c, line 299.
(gdb) run
Starting program: C:\Users\gamef\OneDrive\Desktop\CPE453\program4_tinyfs\a.exe
[New Thread 40396.0x1cc8]
[New Thread 40396.0x6e30]
[New Thread 40396.0x3090]
[New Thread 40396.0x9e38]
Thread 1 hit Breakpoint 1, writeData (begBlock=0, data=0x61fab2 "\001_", 'ÿ' <repeats 31 times>, size=254,
type=DIRECTORY) at TinyFS.c:299
299 Byte buff[BLOCKSIZE] = {0};
(gdb) s
300 buff[MAGIC_OFFSET] = MAGIC_NUMBER;
(gdb) finish
Run till exit from #0 writeData (begBlock=0, data=0x61fab2 "\001_", 'ÿ' <repeats 31 times>, size=254, type=DIRECTORY)
at TinyFS.c:300
PS C:\Users\gamef\OneDrive\Desktop\CPE453\program4_tinyfs>
It seems that this problem is a caused by a bug inside the 8.1 version of GDB. So I reverted back to GDB 8.0 which seems to work perfectly.

Debug when thread is stuck in syscall 32bit program on 64 bit host

I have a problem where one or more threads lock each other. I dont know what going on there. The debugger cannot break (thread 1), breaks but cannot get a backtrace (thread 2+5) or shows the backtrace (thread 3)
Gdb native shows the same.
I learned that this is case because libc imlements this in assembler an gdb cannot walt the stack correctly. Sometimes (i dont know when), i can do a few steps in the assembly, then i see the backtrace.
I just tried a x64 program and it works.
See my sample code:
#include <time.h>
int main()
{
while(1)
{
struct timespec ts;
ts.tv_sec = 1;
ts.tv_nsec = 0;
clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, 0);
}
return 1;
}
gdb output 32 bit:
vagrant#PC41388-spvm-4650:/tmp$ gdb main32
GNU gdb (Ubuntu
7.7.1-0ubuntu5~14.04.2) 7.7.1 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 "x86_64-linux-gnu". 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"... Reading symbols from main32...(no debugging symbols
found)...done.
(gdb) r Starting program: /tmp/main32 [Thread
debugging using libthread_db enabled] Using host libthread_db library
"/lib/x86_64-linux-gnu/libthread_db.so.1". ^C Program received signal
SIGINT, Interrupt. 0x55579cd9 in ?? () (gdb) bt
#0 0x55579cd9 in ?? ()
#1 0x555b0af3 in __libc_start_main (main=0x80484dd , argc=1,
argv=0xffffcee4, init=0x8048520 <__libc_csu_init>,
fini=0x8048590 <__libc_csu_fini>, rtld_fini=0x55564160 <_dl_fini>,
stack_end=0xffffcedc) at libc-start.c:287
#2 0x08048401 in _start () (gdb)
gdb output 64 bit:
vagrant#PC41388-spvm-4650:/tmp$ gdb main64
GNU gdb (Ubuntu
7.7.1-0ubuntu5~14.04.2) 7.7.1 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 "x86_64-linux-gnu". 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"... Reading symbols from main64...(no debugging symbols
found)...done.
(gdb) r Starting program: /tmp/main64 [Thread
debugging using libthread_db enabled] Using host libthread_db library
"/lib/x86_64-linux-gnu/libthread_db.so.1". b ^C Program received
signal SIGINT, Interrupt. 0x00002aaaaafe092a in __clock_nanosleep
(clock_id=1, flags=0,
req=0x7fffffffdc10, rem=0x2aaaaafe092a <__clock_nanosleep+58>)
at ../sysdeps/unix/sysv/linux/clock_nanosleep.c:41 41 ../sysdeps/unix/sysv/linux/clock_nanosleep.c: No such file or
directory.
(gdb) bt
#0 0x00002aaaaafe092a in __clock_nanosleep (clock_id=1, flags=0,
req=0x7fffffffdc10, rem=0x2aaaaafe092a <__clock_nanosleep+58>)
at ../sysdeps/unix/sysv/linux/clock_nanosleep.c:41
#1 0x0000000000400630 in main () (gdb)
set architecture i386 does not help either.
More news: info proc mapp shows the x32 app is in [vvar] whereas the x64 app is at libc. This would explain why gdb cant find the backtrace.
So my question is: Is there a different version of the libc, where this works? I am using ubuntu14.04.
I updated to a newer gdb version (currently the latest, 7.12.1). This fixed the problem.
Note that gbd:i386 did not work either on lubuntu x64, whereas it worked fine under lubuntu x32. Also note that both main32 and libc are binary identical on lubuntu x64 and x32.

Resources