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.
Related
I want to view the content of std::vector<std::string> in GDB nicely
I can view it with just like in this suggestion
print *(myVector._M_impl._M_start)#myVector.size()
But it prints out all stuff that is part of the C++ STL and it is a bit difficult to view the "actual" content of the strings
Is there any way to view the elements nicely without displaying some part of the STL containers?
Is there any way to view the elements nicely without displaying some part of the STL containers?
You either have a very old GDB, or some non-standard setup.
Here is what it looks like on a Fedora-34 system with default GDB installation:
(gdb) list
1 #include <string>
2 #include <vector>
3
4 int main()
5 {
6 std::vector<std::string> v;
7 v.push_back("abc");
8 v.push_back("abcdef");
9 v.push_back("ghi");
10 }
(gdb) b 9
Breakpoint 1 at 0x401378: file t.cc, line 9.
(gdb) run
Starting program: /tmp/a.out
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
Breakpoint 1, main () at t.cc:9
9 v.push_back("ghi");
(gdb) p v
$1 = std::vector of length 2, capacity 2 = {"abc", "abcdef"}
(gdb) n
10 }
(gdb) p v
$2 = std::vector of length 3, capacity 4 = {"abc", "abcdef", "ghi"}
(gdb) q
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.
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.
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
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 ...