lldb fails when setting condition - c++

I compiled my file with clang++ -std=c++17 -g try.cpp
Now on lldb,
(lldb) b Board.cpp:27
Breakpoint 1: where = a.out`Board::move(Point const&, Point const&, std::__1::vector<std::__1::vector<float, std::__1::allocator<float> >, std::__1::allocator<std::__1::vector<float, std::__1::allocator<float> > > > const&, int, float) + 40 at Board.cpp:27:28, address = 0x0000000100001558
(lldb) b Board.cpp:27 -c 'prob==0.1'
Breakpoint 2: no locations (pending).
WARNING: Unable to resolve breakpoint to any actual locations
I am using Mojave,
~ lldb --version
lldb-1001.0.13.3
Swift-5.0
Why is setting -c failed, while omitting it did not?

That's a bug in the b command. The b command isn't the "real" lldb breakpoint setting command - that is break set. b is an lldb "regex" based command that attempts to emulate the gdb breakpoint parser - and then dispatches to break set. It was added so that folks coming from gdb would have an easier time with lldb. But apparently it doesn't handle the -c flag properly. After setting a breakpoint as you specify, you will see:
(lldb) b Board.cpp:27 -c 'prob==0.1'
Breakpoint 1: no locations (pending).
WARNING: Unable to resolve breakpoint to any actual locations.
(lldb) break list
Current breakpoints:
1: name = 'Board.cpp:27 -c prob==0.1', locations = 0 (pending)
So b thought you were trying to set a "function name" breakpoint using the entire string. Please file this with http://bugs.llvm.org.
You can set the breakpoint you were trying to set using break set like:
(lldb) br s -f Board.cpp -l 27 -c 'prob==0.1'

Related

LLDB producing 'A packet returned error 8' when I run my program

I've been trying to locate where a segmentation fault is in a program using LLDB. I've been going to the Ubuntu shell on repl.it and compiling my code using clang++-7 -pthread -std=c++17 -o main main.cpp -g and the program compiles succesfully. Next, I run lldb main and everything's fine but as soon as I type run I get error: process launch failed: 'A' packet returned an error: 8. I've checked the docs and looked up the error but I can't seem to find anything. Thanks for any sort of help!
The full log:
~/Project$ clang++-7 -pthread -std=c++17 -o main main.cpp -g
~/Project$ lldb main
(lldb) target create "main"
Current executable set to 'main' (x86_64).
(lldb) run
error: process launch failed: 'A' packet returned an error: 8
In case you need the code it's on this Github: https://github.com/KingsleyDockerill/Wirth
For those using Docker, as mentioned here, they need to add --cap-add=SYS_PTRACE --security-opt seccomp=unconfined to their docker run command in order to use lldb.
See also this older answer.

gdb fails to insert a breakpoint even if compiled with -no-pie

I'm trying to get gdb working with C++ programs on Ubuntu 20.04. What I need is to be able to set a breakpoint (for example, break main.cpp:3 gdb command) and then run until the breakpoint, but at the moment both start and run fail because they "Cannot insert breakpoint" and "Cannot access memory". For me gdb fails even with very simple examples. This is main.cpp content:
#include <iostream>
int main() {
std::cout << "Hello World!";
return 0;
}
I found somewhere that using -no-pie might help to get gdb working (with breakpoints), so I compile the program by running g++ -ggdb3 -no-pie -o main main.cpp (I also tried -g instead of -ggdb3, and -fno-PIE in addition to -no-pie). When I try to use gdb, it complains "Cannot insert breakpoint 1":
gdb -q main
Reading symbols from main...
(gdb) start
Temporary breakpoint 1 at 0x1189: file main.cpp, line 3.
Starting program: /tmp/main
Warning:
Cannot insert breakpoint 1.
Cannot access memory at address 0x1189
Without -no-pie result is the same. Only thing that changes with or without -no-pie is the hexadecimal address, without -no-pie it is low like 0x1189 (as shown above), with -no-pie it can be 0x401176, but everything else exactly the same, I keep getting the "Cannot access memory at address" warning in both cases.
If I use starti instead of start, it works at first, but after a few nexti iterations it prints usual message "Cannot insteart breakpoint":
gdb -q main
Reading symbols from main...
(gdb) starti
Starting program: /tmp/main
Program stopped.
0x00007ffff7fd0100 in ?? () from /lib64/ld-linux-x86-64.so.2
(gdb) nexti
0x00007ffff7fd0103 in ?? () from /lib64/ld-linux-x86-64.so.2
...
(gdb) nexti
Warning:
Cannot insert breakpoint 0.
Cannot access memory at address 0x4
0x00007ffff7fd0119 in ?? () from /lib64/ld-linux-x86-64.so.2
(gdb) nexti
0x00007ffff7fd011c in ?? () from /lib64/ld-linux-x86-64.so.2
...
(gdb) nexti
Warning:
Cannot insert breakpoint 0.
Cannot access memory at address 0x1c
0x000055555556ca22 in ?? ()
(gdb) nexti
[Detaching after fork from child process 3829827]
...
[Detaching after fork from child process 3829840]
Hello World![Inferior 1 (process 3819010) exited normally]
So I can use nexti, but cannot use next and obviously cannot insert breakpoints.
I tried -Wl,-no-pie (by running g++ -Wl,-no-pie -ggdb3 -o main main.cpp; adding -no-pie does not change anything) but this option causes a strange linker error:
/usr/bin/ld: cannot find -lgcc_s
/usr/bin/ld: cannot find -lgcc_s
collect2: error: ld returned 1 exit status
When I google the error, I only found advice to try -no-pie instead of -Wl,-no-pie, and no other solutions. Since debugging C++ programs is very common activity, I feel like I'm missing something obvious but I found no solution so far.
To make it easier to understand what exact commands I use and to make it clear I'm not mixing up directories and to show what versions of g++ and gdb I'm using, here is full terminal log:
$ ls
main.cpp
$ g++ --version | grep Ubuntu
g++ (Ubuntu 9.3.0-10ubuntu2) 9.3.0
$ g++ -ggdb3 -no-pie -o main main.cpp
$ ls
main main.cpp
$ gdb --version | grep Ubuntu
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04) 9.2
$ readelf -h main | grep 'Type: .*EXEC'
Type: EXEC (Executable file)
$ gdb -q main
Reading symbols from main...
(gdb) start
Temporary breakpoint 1 at 0x401176: file main.cpp, line 3.
Starting program: /tmp/main/main
Warning:
Cannot insert breakpoint 1.
Cannot access memory at address 0x401176
For completeness, I tried the same without -no-pie:
$ rm main
$ g++ -ggdb3 -o main main.cpp
$ readelf -h main | grep 'Type: .*'
Type: DYN (Shared object file)
$ gdb -q main
Reading symbols from main...
(gdb) start
Temporary breakpoint 1 at 0x1189: file main.cpp, line 3.
Starting program: /tmp/main/main
Warning:
Cannot insert breakpoint 1.
Cannot access memory at address 0x1189
As you can see the only difference with or without -no-pie is the memory address, but the issue and warnings are the same. Without -no-pie this may be expected, but I do not understand why this is happening if I compiled with -no-pie and what else I can try to solve the issue.
This:
g++ -ggdb3 -no-pie -o main main.cpp
should produce a non-PIE executable. You should be able to verify that it non-PIE by looking at readelf -h main | grep 'Type: .*EXEC' (PIE binaries have ET_DYN type).
This:
Temporary breakpoint 1 at 0x1189: file main.cpp, line 3.
is unambiguously a PIE binary (a non-PIE binary will not have any code below 0x40000 on x86_64 Linux).
Conclusion: you are either debugging the wrong binary (e.g. you are compiling main in a different directory from the one in which you are debugging), or you are not telling is the whole story.

Why is "gdb" listing multiple functions after executing the "start' command even when the C++ source file doesn't contain any function?

The context
Consider the following file
$ cat main.cpp
int main() {return 0;}
I can list all the available functions by executing
$ g++ -g main.cpp && gdb -q -batch -ex 'info functions -n' a.out
All defined functions:
File main.cpp:
1: int main();
When executing start before executing info functions more than 1000 functions are listed (see below)
g++ -g main.cpp && \
gdb -q -batch -ex 'start' -ex 'info functions -n' a.out | \
head -n 10
Temporary breakpoint 1 at 0x111d: file main.cpp, line 1.
Temporary breakpoint 1, main () at main.cpp:1
1 int main() {return 0;}
All defined functions:
File /build/gcc/src/gcc-build/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/allocated_ptr.h:
70: void std::__allocated_ptr<std::allocator<std::_Sp_counted_ptr_inplace<std::filesystem::__cxx11::filesystem_error::_Impl, std::allocator<std::filesystem::__cxx11::filesystem_error::_Impl>, (__gnu_cxx::_Lock_policy)2> > >::~__allocated_ptr();
70: void std::__allocated_ptr<std::allocator<std::_Sp_counted_ptr_inplace<std::filesystem::filesystem_error::_Impl, std::allocator<std::filesystem::filesystem_error::_Impl>, (__gnu_cxx::_Lock_policy)2> > >::~__allocated_ptr();
As seen below, the total number of lines printed is so, apparently, more than 1000 functions are being listed
g++ -g main.cpp && gdb -q -batch -ex 'start' -ex 'info functions -n' a.out | wc -l
4436
The question
As we can see above, the main.cpp file does not contain any function, so why is gdb listing those functions when the start command has been executed before but not when start hasn't been executed?
Additional context
As suggested in one of the comments of this question, here's the output of executing info shared after start has been executed
g++ -g main.cpp && gdb -q -batch -ex 'start' -ex 'info shared' a.out
Temporary breakpoint 1 at 0x111d: file main.cpp, line 1.
Temporary breakpoint 1, main () at main.cpp:1
1 int main() {return 0;}
From To Syms Read Shared Object Library
0x00007ffff7fd2090 0x00007ffff7ff2746 Yes (*) /lib64/ld-linux-x86-64.so.2
0x00007ffff7e4c040 0x00007ffff7f37b52 Yes /usr/lib/libstdc++.so.6
0x00007ffff7c7f3b0 0x00007ffff7d1a658 Yes (*) /usr/lib/libm.so.6
0x00007ffff7c59020 0x00007ffff7c69ca5 Yes /usr/lib/libgcc_s.so.1
0x00007ffff7ab3650 0x00007ffff7bfe6bd Yes (*) /usr/lib/libc.so.6
(*): Shared library is missing debugging information.
main.cpp file does not contain any function, so why is gdb listing those functions when the start command has been executed before but not when start hasn't been executed?
Before start, GDB reads symbols (and debug info) only for the main executable.
After start, a dynamically linked executable loads shared libraries (seen in info shared), and GDB (by default) reads symbol tables and debug info for each of them. And since these libraries contain hundreds of functions, GDB knows about all of them.
You can prevent this with set auto-solib-add off, but usually you don't want to do that. If you do, and your program crashes in e.g. abort, GDB will not know where you crashed unless you manually add the symbols back using sharedlibrary or add-symbol-file command.

gdb cannot find source file of libarary

I want to debug with stander library in gdb.
I ran gdb with argument -d to specify the source file of standard libary.
$ gdb ./test -d /usr/src/glibc/glibc-2.27/
test.cpp:
#include<iostream>
#include<string>
using namespace std;
int main(){
string hex("0x0010");
long hex_number = strtol(hex.c_str(), NULL, 16);
cout << hex_number << endl;
return 0;
}
However, gdb told me it can not find source file strtol.c.
(gdb) b 8
Breakpoint 1 at 0xc8c: file /home/purin/Desktop/CodeWork/adv_unix_programming/hw1/test.cpp, line 8.
(gdb) run
Starting program: /home/purin/Desktop/CodeWork/adv_unix_programming/hw1/test
Breakpoint 1, main () at /home/purin/Desktop/CodeWork/adv_unix_programming/hw1/test.cpp:8
8 long hex_number = strtol(hex.c_str(), NULL, 16);
(gdb) s
__strtol (nptr=0x7fffffffd820 "0x0010", endptr=0x0, base=16) at ../stdlib/strtol.c:106
106 ../stdlib/strtol.c: file or directory does not exits
(gdb) info source
Current source file is ../stdlib/strtol.c
Compilation directory is /build/glibc-OTsEL5/glibc-2.27/stdlib
Source language is c.
Producer is GNU C11 7.3.0 -mtune=generic -march=x86-64 -g -O2 -O3 -std=gnu11 -fgnu89-inline -fmerge-all-constants -frounding-math -fstack-protector-strong -fPIC -ftls-model=initial-exec -fstack-protector-strong.
Compiled with DWARF 2 debugging format.
Does not include preprocessor macro info.
Since gdb can find source code if I execute this command:
(gdb) dir /usr/src/glibc/glibc-2.27/stdlib/
I am sure that I have strtol.c in path /usr/src/glibc/glibc-2.27/stdlib/strtol.c and the library has debug information.
Why gdb cannot search the directories under /usr/src/glibc/glibc-2.27/ to find out stdlib/strtol.c?
Maybe the reason is that if you join two paths /usr/src/glibc/glibc-2.27/ and ../stdlib/strtol.c you get the path /usr/src/glibc/stdlib/strtol.c, but not the expected path /usr/src/glibc/glibc-2.27/stdlib/strtol.c. The reason why ../stdlib/strtol.c is stored in the debug info, very likely is a build directory /build/glibc-OTsEL5/glibc-2.27/build used, and ../stdlib/strtol.c is the relative path to the build directory.
One of solutions is run
$ gdb ./test -d /usr/src/glibc/glibc-2.27/stdlib/

What is the lldb equivalent of gdb's --args?

I'm used to running gdb like so:
$ gdb --args exe --lots --of --flags -a -b -c d e
...
(gdb) r
Is there an equivalent for lldb?
Yes, it's just -- instead of --args. From the help:
lldb -v [[--] <PROGRAM-ARG-1> [<PROGRAM_ARG-2> ...]]
Thus:
$ lldb -- exe --lots --of --flags -a -b -c d e
You can also start lldb first and use:
(lldb) settings set target.run-args 1 2 3
(lldb) run
or:
(lldb) process launch -- <args>