Why watchpoint doesn't effect? - gdb

I am studying the watchpoint of GDB. I write a simple test code as following:
int main(int argc, char **argv)
{
int x = 30;
int y = 10;
x = y;
return 0;
}
I build it via gcc -g -o wt watch.c. And then I started gdb and did following experiment:
lihacker#lihacker-laptop:~/mySrc$ gdb ./wt
GNU gdb (GDB) 7.3
Copyright (C) 2011 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 "i686-pc-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/lihacker/mySrc/wt...done.
(gdb) b main
Breakpoint 1 at 0x80483a5: file watch.c, line 5.
(gdb) run
Starting program: /home/lihacker/mySrc/wt
Breakpoint 1, main (argc=<optimized out>, argv=<optimized out>) at watch.c:5
5 int x = 30;
(gdb) watch x
Hardware watchpoint 2: x
(gdb) c
Continuing.
Watchpoint 2 deleted because the program has left the block in
which its expression is valid.
0xb7e83775 in __libc_start_main () from /lib/tls/i686/cmov/libc.so.6
(gdb)
In my test codes, the variable "x" is changed, but gdb doesn't stop then.
Why the watchpoint doesn't effect here? Thanks a lot.

This:
Breakpoint 1, main (argc=<optimized out>, argv=<optimized out>) at watch.c:5
suggests that you used -O2 or some such flag when building the test. Try building with -O0 (which will explicitly disable optimization).
Even then, there is a glitch (a buglet) in GDB. Here is what I see:
(gdb) b main
Breakpoint 3 at 0x80483ba: file t.c, line 3.
(gdb) r
Breakpoint 3, main (argc=1, argv=0xffffca94) at t.c:3
3 int x = 30;
(gdb) watch x
Hardware watchpoint 4: x
(gdb) c
Hardware watchpoint 4: x
Old value = 0
New value = 10
main (argc=1, argv=0xffffca94) at t.c:8
8 return 0;
(gdb) c
Watchpoint 4 deleted because the program has left the block in
which its expression is valid.
0xf7e7cbd6 in __libc_start_main () from /lib32/libc.so.6
This can't be right: the value of x changes from 30 to 10, not from 0 to 10.
If I set the breakpoint on the very first instruction of main, then it works as expected:
(gdb) b *main
Breakpoint 1 at 0x80483b4: file t.c, line 2.
(gdb) r
Breakpoint 1, main (argc=1, argv=0xffffca94) at t.c:2
2 {
(gdb) watch x
Hardware watchpoint 2: x
(gdb) c
Hardware watchpoint 2: x
Old value = 0
New value = 30
main (argc=1, argv=0xffffca94) at t.c:4
4 int y = 10;
(gdb) c
Hardware watchpoint 2: x
Old value = 30
New value = 10
main (argc=1, argv=0xffffca94) at t.c:8
8 return 0;
(gdb) c
Watchpoint 2 deleted because the program has left the block in
which its expression is valid.
0xf7e7cbd6 in __libc_start_main () from /lib32/libc.so.6

Related

Why cuda-gdb shows unexpected memory values?

I am compiling the following fragment of code with nvcc -g -G gdbfail.cu.
#include <cstdio>
#include <cinttypes>
__global__ void mykernel() {
uint8_t* ptr = (uint8_t*) malloc(8);
for (int i = 0; i < 8; i++) {
ptr[i] = 7 - i;
}
for (int i = 0; i < 8; i++) { // PUT BREAKPOINT HERE
printf("%" PRIx8 " ", ptr[i]);
}
printf("\n");
}
int main() {
uint8_t* ptr = (uint8_t*) malloc(8);
for (int i = 0; i < 8; i++) {
ptr[i] = 7 - i;
}
for (int i = 0; i < 8; i++) { // PUT BREAKPOINT HERE
printf("%" PRIx8 " ", ptr[i]);
}
printf("\n");
mykernel<<<1,1>>>();
cudaDeviceSynchronize();
}
When I run cuda-gdb ./a.out and put breakpoint at line 10 (b 10), run the code (r), and trying to print values at the address located in ptr I get surprising results
(cuda-gdb) x/8b ptr
0x7fffcddff920: 7 6 5 4 3 2 1 0
(cuda-gdb) x/8b 0x7fffcddff920
0x7fffcddff920: 0 0 0 0 0 0 0 0
When I am doing the same thing in the host code (b 23, r), I get expected results:
(cuda-gdb) x/8b ptr
0x5555556000a0: 7 6 5 4 3 2 1 0
(cuda-gdb) x/8b 0x5555556000a0
0x5555556000a0: 7 6 5 4 3 2 1 0
Why cuda-gdb doesn't show correct memory values when it is provided with address as a number (0x7fffcddff920) instead of a symbol (ptr)?
Evidently, not all gdb command features that are usable in host code are also usable in device code. When used in device code, the supported commands may have different syntax or expectations. This is indicated in the cuda-gdb docs.
Those docs indicate that the way to inspect memory is the print command and indicate some additional decode syntax that is needed for a "bare" address/pointer. Here is your example:
$ cuda-gdb ./t1869
NVIDIA (R) CUDA Debugger
11.4 release
Portions Copyright (C) 2007-2021 NVIDIA Corporation
GNU gdb (GDB) 10.1
Copyright (C) 2020 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-pc-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 ./t1869...
(cuda-gdb) b 10
Breakpoint 1 at 0x403b05: file t1869.cu, line 14.
(cuda-gdb) r
Starting program: /home/user2/misc/t1869
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
7 6 5 4 3 2 1 0
[Detaching after fork from child process 25822]
[New Thread 0x7fffef475700 (LWP 25829)]
[New Thread 0x7fffeec74700 (LWP 25830)]
[Switching focus to CUDA kernel 0, grid 1, block (0,0,0), thread (0,0,0), device 0, sm 0, warp 0, lane 0]
Thread 1 "t1869" hit Breakpoint 1, mykernel<<<(1,1,1),(1,1,1)>>> () at t1869.cu:10
10 for (int i = 0; i < 8; i++) { // PUT BREAKPOINT HERE
(cuda-gdb) x/8b ptr
0x7fffbcdff920: 7 6 5 4 3 2 1 0
(cuda-gdb) p/x *(#global unsigned char *)0x7fffbcdff920#8
$1 = {0x7, 0x6, 0x5, 0x4, 0x3, 0x2, 0x1, 0x0}
(cuda-gdb)
Note the above print command needs some help in interpreting which "space" you are expecting the memory address to refer to (e.g. #shared, #global, etc.)
If we give your command the same "help" we get the expected result:
(cuda-gdb) x/8b ptr
0x7fffbcdff920: 7 6 5 4 3 2 1 0
(cuda-gdb) x/8b (#global unsigned char *)0x7fffbcdff920
0x7fffbcdff920: 7 6 5 4 3 2 1 0
(cuda-gdb)

Mysterious write violation on my variable

I have an library that don't give correct output. I guess it is possibly an write violation, and focused it on this section of code:
void Page::build_default_frame(PosType genome_display_length)
{
Frame* frame = new Frame(*this,
margin_left,
margin_top,
width - margin_left - margin_right,
genome_display_length);
default_frame = frame;
frames.insert(default_frame);
}
The default_frame is a boost intrusive_ptr<Frame>.
Before execute the sentence default_frame = frame, the content of object frame was all right, but after that, its contents were modified to weird value. So I set two watches on two member variables of frame object:
(gdb) watch -l frame->genome_scale.genome_display_length
Hardware watchpoint 4: -location frame->genome_scale.genome_display_length
(gdb) watch -l frame->genome_scale.frame_width
Hardware watchpoint 5: -location frame->genome_scale.frame_width
and then continue. It suddenly reports write operation on these address:
(gdb) c
Continuing.
Hardware watchpoint 4: -location frame->genome_scale.genome_display_length
Old value = 1000
New value = 16
_dl_runtime_resolve () at ../sysdeps/x86_64/dl-trampoline.S:39
39 ../sysdeps/x86_64/dl-trampoline.S: No such file or directory.
(gdb) bt
#0 _dl_runtime_resolve () at ../sysdeps/x86_64/dl-trampoline.S:39
#1 0x00007ffff7b93dd0 in geno_eye::Page::build_default_frame (this=0x6071b0, genome_display_length=1000)
at /home/yangxi/projects/GenoEye/src/geno_eye/Page.cpp:127
#2 0x00007ffff7b93cc1 in geno_eye::Page::Page (this=0x6071b0, context=0x607750, width=300, height=300,
genome_display_length=1000) at /home/yangxi/projects/GenoEye/src/geno_eye/Page.cpp:29
#3 0x00000000004016b8 in geno_eye::__tester__::run (this=0x7fffffffe1c8)
at /home/yangxi/projects/GenoEye/t/t_page.cpp:15
#4 0x00000000004015d1 in main () at /home/yangxi/projects/GenoEye/t/t_page.cpp:36
(gdb) c
Continuing.
Hardware watchpoint 5: -location frame->genome_scale.frame_width
Old value = 240
New value = 3.1228427039313504e-317
_dl_runtime_resolve () at ../sysdeps/x86_64/dl-trampoline.S:40
40 in ../sysdeps/x86_64/dl-trampoline.S
(gdb) bt
#0 _dl_runtime_resolve () at ../sysdeps/x86_64/dl-trampoline.S:40
#1 0x00007ffff7b93dd0 in geno_eye::Page::build_default_frame (this=0x6071b0, genome_display_length=1000)
at /home/yangxi/projects/GenoEye/src/geno_eye/Page.cpp:127
#2 0x00007ffff7b93cc1 in geno_eye::Page::Page (this=0x6071b0, context=0x607750, width=300, height=300,
genome_display_length=1000) at /home/yangxi/projects/GenoEye/src/geno_eye/Page.cpp:29
#3 0x00000000004016b8 in geno_eye::__tester__::run (this=0x7fffffffe1c8)
at /home/yangxi/projects/GenoEye/t/t_page.cpp:15
#4 0x00000000004015d1 in main () at /home/yangxi/projects/GenoEye/t/t_page.cpp:36
The two old values are the correct values for that two member variables. This write operation is happened before executing the = function of boost intrusive_ptr, as I pressed tens of "next", and the code is still in file dl-trampoline.S.
(gdb) n
41 in ../sysdeps/x86_64/dl-trampoline.S
(gdb) n
42 in ../sysdeps/x86_64/dl-trampoline.S
(gdb) n
43 in ../sysdeps/x86_64/dl-trampoline.S
(gdb) n
44 in ../sysdeps/x86_64/dl-trampoline.S
(gdb) n
45 in ../sysdeps/x86_64/dl-trampoline.S
(gdb) n
46 in ../sysdeps/x86_64/dl-trampoline.S
(gdb) n
47 in ../sysdeps/x86_64/dl-trampoline.S
(gdb) n
48 in ../sysdeps/x86_64/dl-trampoline.S
(gdb) n
49 in ../sysdeps/x86_64/dl-trampoline.S
(gdb) n
50 in ../sysdeps/x86_64/dl-trampoline.S
(gdb) n
51 in ../sysdeps/x86_64/dl-trampoline.S
(gdb) n
52 in ../sysdeps/x86_64/dl-trampoline.S
(gdb) n
53 in ../sysdeps/x86_64/dl-trampoline.S
(gdb) n
54 in ../sysdeps/x86_64/dl-trampoline.S
(gdb) n
56 in ../sysdeps/x86_64/dl-trampoline.S
(gdb) n
boost::intrusive_ptr<geno_eye::Frame>::operator= (this=0x6071b0, rhs=0x3e8)
at /usr/include/boost/smart_ptr/intrusive_ptr.hpp:134
134 {
What is dl-trampoline.S ? Why it silently write on the memory of my object?
In addition of that, I also run valgrind:
$ valgrind ./t_page
However, instead of invalid write, it reports invalid read to that object, which is happened after the object creation is finished.
This is caused by an reference-to-stack bug.
Object genome_scale holds two references to two member variables of frame object. When I reconstruct my code, it accidentally reference to two stack variables...
So, maybe I should avoid the use of reference types in this situation, as you can easily provide stack stuffs to them and don't get any warns.

Simple code cause error reading variable: Cannot access memory at address

I am trying to use a python-enabled gdb MinGW-builds. And I run into an error. This is a rather simple code, and It works fine when debugging under MSVC.
D:\CppProject\c1\bin\Debug>gdb c1.exe
GNU gdb (GDB) 7.6
(copyright, license, bug report, etc omitted here)
Reading symbols from D:\CppProject\c1\bin\Debug\c1.exe...done.
(gdb) l
1 #include <iostream>
2 #include <vector>
3
4 using namespace std;
5
6 int main()
7 {
8 vector<string> v;
9 v.push_back("first");
10 v.push_back("second");
(gdb)
11 cout<<v[0]<<endl;
12 cout<<v[1]<<endl;
13
14 return 0;
15 }
(gdb) break 11
Breakpoint 1 at 0x4016c9: file D:\CppProject\c1\main.cpp, line 11.
(gdb) run
Starting program: D:\CppProject\c1\bin\Debug\c1.exe
[New Thread 1256.0xbe8]
Breakpoint 1, main () at D:\CppProject\c1\main.cpp:11
11 cout<<v[0]<<endl;
(gdb) p v
$1 = std::vector of length 2, capacity 2 = {"first", "second"}
(gdb) p v[0]
$2 = <error reading variable: Cannot access memory at address 0x29a2ca50>
This may sound basic - did you compile with -O0 ? I suspect that compiler optimization might cause your trouble.

GDB tracing: No current trace frame

I am trying GDB tracepoints, but I can't get any data. I start gdbserver as following:
$ gdbserver :1234 ./a.out
Process ./a.out created; pid = 13610
Listening on port 1234
I then use the following commands on my client:
$ gdb ./a.out
...
Reading symbols from /home/simark/src/test/a.out...done.
(gdb) target remote :1234
Remote debugging using :1234
Reading symbols from /lib64/ld-linux-x86-64.so.2...done.
Reading symbols from /usr/lib/debug/lib/x86_64-linux-gnu/ld-2.15.so...done.
Loaded symbols for /lib64/ld-linux-x86-64.so.2
0x00007ffff7ddb6c0 in _start () from /lib64/ld-linux-x86-64.so.2
(gdb) l
1 #include <stdio.h>
2 int foo(int a, int b) {
3 return a + b + b;
4 }
5
6 int main() {
7 int n = foo(33, 4);
8 printf("%d\n", n);
9 return 0;
10 }
(gdb) trace 3
Tracepoint 1 at 0x400526: file test.c, line 3.
(gdb) b 9
Breakpoint 2 at 0x400563: file test.c, line 9.
(gdb) actions 1
Enter actions for tracepoint 1, one per line.
End with a line saying just "end".
>collect $regs,$args
>end
(gdb) tstart
(gdb) c
Continuing.
Breakpoint 2, main () at test.c:9
9 return 0;
(gdb) tstop
(gdb) tdump
warning: No current trace frame.
(gdb)
According to the examples I saw on the web, I should have one event, because control passed over my tracepoint. Any ideas why I get no data?
According to the examples I saw on the web, I should have one event, because control passed over my tracepoint.
You forgot to do tfind start before doing tdump. From help tdump:
Print everything collected at the current tracepoint.
But you are not stopped at any tracepoint, you are stopped at breakpoint#2.
The tfind start selects the first trace frame in the trace buffer.

gdb: Meaning of tstart error "You can't do that when your target is `exec'"

I would like to record the value of a local variable, t, each time that the program reaches a certain line. Accordingly, I tried:
(gdb) trace stoer_wagner_min_cut.hpp :197
Tracepoint 1 at 0x4123a0: file ./boost/graph/stoer_wagner_min_cut.hpp, line 197.
(gdb) actions
Enter actions for tracepoint 1, one per line.
End with a line saying just "end".
> collect t
> end
(gdb) tstart
You can't do that when your target is `exec'
(gdb) break main
Breakpoint 2 at 0x401448: file time_stoer_wagner.cpp, line 50.
(gdb) run
Starting program: C:\Users\Daniel\Documents\projects\stoer_wagner_min_cut/time_stoer_wagner.exe
[New Thread 3908.0x39c]
Breakpoint 2, main () at time_stoer_wagner.cpp:50
50 std::ifstream ifs("prgen_500_50_2.txt");
(gdb) tstart
You can't do that when your target is `child'
but the error messages "You can't do that when your target is `exec'" and "You can't do that when your target is `child'" are not helpful to me. What do these errors mean?
The tracepoint facility is currently available only for remote targets.
You should be able to perform the tracing experiment you desire by using gdbserver. Example:
$ gdbserver :0 ./a.out
Process ./a.out created; pid = 21838
Listening on port 51596
In another window:
$ gdb -q ./a.out
Reading symbols from /tmp/a.out...done.
(gdb) target remote :51596
0x00007fa76ec3fa60 in _start () from /lib64/ld-linux-x86-64.so.2
(gdb) list foo
1 int foo(int x)
2 {
3 return x;
4 }
5
6 int main()
7 {
8 for(int i = 0; i < 10; ++i)
9 foo(i);
10 return 0;
11 }
(gdb) trace 3
Tracepoint 1 at 0x40053f: file t.c, line 3.
(gdb) actions
> collect x
> end
(gdb) c
Tracing experiment now collects the data ...