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)
Related
Given a program:
[]$ cat a.cpp
#include <iostream>
int main(){
auto [a, b] = std::make_pair(1, 2);
for(int x = 0; x < 2; ++x) {
a += b;
b += x;
}
}
If I compile it and step through it line by line in GDB:
[]$ g++ -std=c++17 -g a.cpp
[]$ gdb -q a.out
Reading symbols from a.out...
(gdb) break main
Breakpoint 1 at 0x114d: file a.cpp, line 4.
(gdb) run
Starting program: /tmp/a.out
Breakpoint 1, main () at a.cpp:4
4 auto [a, b] = std::make_pair(1, 2);
(gdb) next
5 for(int x = 0; x < 2; ++x) {
(gdb)
4 auto [a, b] = std::make_pair(1, 2);
(gdb)
6 a += b;
(gdb)
4 auto [a, b] = std::make_pair(1, 2);
(gdb)
7 b += x;
(gdb)
5 for(int x = 0; x < 2; ++x) {
(gdb)
4 auto [a, b] = std::make_pair(1, 2);
(gdb)
6 a += b;
(gdb)
4 auto [a, b] = std::make_pair(1, 2);
(gdb)
7 b += x;
(gdb)
5 for(int x = 0; x < 2; ++x) {
(gdb)
9 }
Then the structured binding declaration line is stepped over every time the variable is accessed or written to.
Is there any way so that it does not step through those lines, expect for the first time, similar to this:
(gdb) run
Starting program: /tmp/a.out
Breakpoint 1, main () at a.cpp:4
4 auto [a, b] = std::make_pair(1, 2);
(gdb) next
5 for(int x = 0; x < 2; ++x) {
(gdb)
6 a += b;
(gdb)
7 b += x;
(gdb)
5 for(int x = 0; x < 2; ++x) {
(gdb)
6 a += b;
(gdb)
7 b += x;
(gdb)
5 for(int x = 0; x < 2; ++x) {
(gdb)
9 }
It's possible to change the structured binding to auto& a = pair.first; auto& b = pair.second and it works correctly, but it means not using structured binding at all.
Setting a breakpoint at the line and enter command commands | next | end does not completely work, and still require manual work for each structured binding.
Adding any optimization flag (even -Og in this case) optimize the whole code away (because it doesn't have any observable side effect); or optimizes some unused variables away.
When there are observable side effect however, it does work.
Searching online for "gdb debug structured binding", or even "gdb skip through particular line while stepping" does not give any useful result. The skip command can only skip through functions, not lines.
Tools version:
[]$ g++ --version
g++ (Arch Linux 9.2.1+20200130-2) 9.2.1 20200130
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
[]$ gdb --version
GNU gdb (GDB) 9.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.
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 have a project in C++ using marray library. For now it compiles and runs quite fine with MinGW g++ 4.7 and msvc2010 on Windows 7 x64 and also with g++ 4.7 on Linux Mint x64. I decided to give a try to Intel C++ compiler v. 12.1.4 for Linux. It was able to compile the code but when it tries to execute any line bothering expression templates (like c = a + b where all three terms are matrices) it breaks down with segmentation fault. This issue affects both debug and release versions of the app.
I also tried to compile unit tests and tutorial code for marray library and again, Intel C++ compiles the code but fails to run it if it has any expression templates. Is Intel C++ really as bad with deep templates or am I missing something? Do I need to set any special compiler flags to make template expressions work? Or maybe it is just something wrong with the particular library I'm using, not the expression templates technique in general?
I also tried to set the -ftemplate-depth-n flag using a wide variety on n up to ridiculously large values of 10^10 and still had no luck in running neither my app nor marray unit tests/tutorial without the segmentation fault.
Upd.: Here is the gdb log for tutorial-marray from the mentioned library compiled with icpc in debug mode.
GNU gdb (Ubuntu/Linaro 7.3-0ubuntu2) 7.3-2011.08
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 "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://bugs.launchpad.net/gdb-linaro/>...
Reading symbols from /home/dmitry/SOFT/Development/marray_orig/tutorial-marray...done.
(gdb) l 126
121 size_t shape[] = {3, 4, 2};
122 marray::Marray<int> a(shape, shape + 3, 2);
123 marray::Marray<int> b(shape, shape + 3, 2);
124 marray::Marray<int> c;
125
126 ++a;
127 --a;
128
129 a += 2;
130 a -= 2;
(gdb) break 126
Breakpoint 1 at 0x452de8: file /home/dmitry/SOFT/Development/marray_orig/marray/src/tutorial/tutorial.cxx, line 126.
(gdb) run
Starting program: /home/dmitry/SOFT/Development/marray_orig/tutorial-marray
A(c,r,0) =
1 0 0
0 0 0
0 0 0
0 0 0
A(c,r,1) =
0 0 0
0 0 0
0 0 0
0 0 2
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2
Breakpoint 1, main () at /home/dmitry/SOFT/Development/marray_orig/marray/src/tutorial/tutorial.cxx:126
126 ++a;
(gdb) next
127 --a;
(gdb) next
129 a += 2;
(gdb) next
130 a -= 2;
(gdb) next
131 a /= 2;
(gdb) next
132 a *= 2;
(gdb) next
134 c = a + b;
(gdb) next
Program received signal SIGSEGV, Segmentation fault.
0x0000000000420fcf in marray::ViewExpression<marray::View<int, false, std::allocator<unsigned long> >, int>::operator marray::View<int, false, std::allocator<unsigned long> > const& (this=0x7fffffffcd88)
at /home/dmitry/SOFT/Development/marray_orig/marray/include/marray/marray.hxx:5409
5409 { return static_cast<const E&>(*this); }
(gdb)
Looks like the problem doesn't originate from the expression template technique in general, array arithmetics with numbers works fine. The problem arises when I'm trying to add one array to another.
Upd. 2: Actually the whole thing looks quite like the problem mentioned here. The solution should be in rewriting operator E&() { return static_cast(*this); } into something like E& get_ref() { return static_cast(*this); } and the same thing for const reference. And, of course, change the usage of these things within the code. Will try it as soon as I can and report the results.
The problem is similar to the one reported here. The actual reason of the issue is that the code generated by Intel C++ compiler handles expressions like this:
operator E&()
{
return static_cast<E&>(*this);
}
as recursive calls of this operator. A simple workaround is to change the operator into method like
E& get_ref()
{
return static_cast<E&>(*this);
}
The drawback is that you have to change every line of code which used that operator. Fortunately, it wasn't too hard with the mentioned marray library, so now both my app and the tutorials and unit tests of that library work like a charm with Intel C++ compiler.
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 ...