I'm trying to debug a C++ program. I'm on macOS, using CLion IDE, clang compiler, LLDB. I stop the program at a breakpoint (marked with >>):
UnicodeString unicodeFromFile(const std::string &file) {
std::ifstream input(file, std::ios::binary);
cout << "open? " << input.is_open() << endl;
>> std::vector<char> bytes(...);
I want to run po input.is_open(). LLDB reports:
(lldb) po input.is_open()
error: expression failed to parse:
error: <user expression 0>:1:7: call to member function 'is_open' is ambiguous
input.is_open()
~~~~~~^~~~~~~
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.3.sdk/usr/include/c++/v1/fstream:1169:10: candidate function
bool is_open() const;
^
But it's obviously not ambiguous, since the previous line of code calls it without problem. And it's error message is only listing one function.
Previous to this, I had a different problem where it couldn't find the symbol at all. But I used the advice here, which got me to this point. That answer says to add this to to ~/.lldbinit:
settings set target.import-std-module true
My previous errors looked like:
(lldb) po input.is_open()
error: expression failed to parse:
error: Couldn't lookup symbols:
__ZNKSt3__114basic_ifstreamIcNS_11char_traitsIcEEE7is_openEv
When I try this trivial case with the most recent Xcode (or with TOT lldb) calling the is_open works:
> cat tryifstream.cpp
#include <fstream>
int
main() {
std::ifstream my_str("/tmp/tryifstream.cpp");
bool is_it = my_str.is_open();
return is_it ? 0 : 20;
}
> clang++ -g -O0 /tmp/tryifstream.cpp -o /tmp/a.out
> lldb /tmp/a.out
(lldb) b s -p return
Breakpoint 1: where = a.out`main + 88 at tryifstream.cpp:7:10, address = 0x000000010000379c
(lldb) run
Process 38065 launched: '/tmp/a.out' (arm64)
Process 38065 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
frame #0: 0x000000010000379c a.out`main at tryifstream.cpp:7
4 main() {
5 std::ifstream my_str("/tmp/tryifstream.cpp");
6 bool is_it = my_str.is_open();
-> 7 return is_it ? 0 : 20;
^
8 }
Target 0: (a.out) stopped.
(lldb) v is_it
(bool) is_it = true
(lldb) expr my_str.is_open()
(bool) $0 = true
If this simple case fails for you, you might try upgrading your Xcode. Getting the lldb expression parser to handle all of std templates is an area of ongoing work and newer lldb's are generally better at it.
If that simple case works for you, but your "real" case still doesn't, and you can make your project or some reduced reproducer available to us, please file a bug with the llvm.org bug reporter, including a copy of your reproducer. It will be hard to figure out what's going wrong in this case w/o being able to trace through the lookups.
Related
int main()
{
typedef unsigned char a4[4];
a4 p1;
a4& p2 = p1;
p2[1]=1;
cout<<sizeof(p2);
return p2[1];
}
Compile, start gdb and put breakpoint on return. If you type p sizeof(p2), gdb will print 8 instead of 4 which will be printed if you start the program. If you write in gdb p sizeof(*p2), the output is 4 (the size of array). I think this is because gdb treats p2 as pointer(reference is implemented behind the scene as pointer).
Tested with compilers GCC 4.8.2 and Clang 4.3 on GDB 7.7 linux arch., ubuntu 13.10,
Is this correct or a bug in gdb?
Here's a modified version of your program. I've changed the array size from 4 to 17 to ensure that its size is distinguishable from anything else. I've also changed the type and variable names to make the code easier to follow, and added #include <iostream> so it actually compiles. I've also removed some unnecessary stuff.
#include <iostream>
int main()
{
typedef unsigned char char17[17];
char17 arr17;
char17& arr17_ref = arr17;
std::cout << "sizeof(arr17) = "
<< sizeof arr17
<< ", sizeof(arr17_ref) = "
<< sizeof(arr17_ref)
<< "\n";
return 0;
}
When I compile and run it on my system, the output is 17.
When I run it under gdb, I get 8 (the size of a pointer on my system):
$ gdb ./c
GNU gdb (GDB) 7.5-ubuntu
[snip]
Reading symbols from /home/kst/c...done.
(gdb) b 12
Breakpoint 1 at 0x40097e: file c.cpp, line 12.
(gdb) r
Starting program: /home/kst/c
sizeof(arr17) = 17, sizeof(arr17_ref) = 17
Breakpoint 1, main () at c.cpp:12
12 return 0;
(gdb) p sizeof(arr17)
$1 = 17
(gdb) p sizeof(arr17_ref)
$2 = 8
(gdb) c
Continuing.
[Inferior 1 (process 23420) exited normally]
(gdb) q
$
Yes, this is a bug in gdb. gdb is supposed to evaluate expressions as they'd be evaluated in a running program; in this case, it fails to do so.
(I'm using gcc 4.7.2 and gdb 7.5 on Linux Mint 14.)
UPDATE :
The OP submitted a bug report: https://sourceware.org/bugzilla/show_bug.cgi?id=16675
and it's been fixed. The patch was approved and committed 2014-04-14. I still see the bug in gdb 7.7.1, but it's fixed in 7.11.1.
I prepared a C++ interface to a legacy Fortran library.
Some subroutines in the legacy library follow an ugly but usable status code convention to report errors, and I use such status codes to throw a readable exception from my C++ code: it works great.
On the other hand, sometimes the legacy library calls STOP (which terminates the program). And it often does it even though the condition is recoverable.
I would like to capture this STOP from within C++, and so far I have been unsuccessful.
The following code is simple, but exactly represents the problem at hand:
The Fortran legacy library fmodule.f90:
module fmodule
use iso_c_binding
contains
subroutine fsub(x) bind(c, name="fsub")
real(c_double) x
if(x>=5) then
stop 'x >=5 : this kills the program'
else
print*, x
end if
end subroutine fsub
end module fmodule
The C++ Interface main.cpp:
#include<iostream>
// prototype for the external Fortran subroutine
extern "C" {
void fsub(double& x);
}
int main() {
double x;
while(std::cin >> x) {
fsub(x);
}
return 0;
}
The compilation lines (GCC 4.8.1 / OS X 10.7.4; $ denotes command prompt ):
$ gfortran -o libfmodule.so fmodule.f90 -shared -fPIC -Wall
$ g++ main.cpp -L. -lfmodule -std=c++11
The run:
$ ./a.out
1
1.0000000000000000
2
2.0000000000000000
3
3.0000000000000000
4
4.0000000000000000
5
STOP x >=5 : this kills the program
How could I capture the STOP and, say, request another number. Notice that I do not want to touch the Fortran code.
What I have tried:
std::atexit: cannot "come back" from it once I have entered it
std::signal: STOP does not seem to throw a signal which I can capture
You can solve your problem by intercepting the call to the exit function from the Fortran runtime. See below. a.out is created with your code and the compilation lines you give.
Step 1. Figure out which function is called. Fire up gdb
$ gdb ./a.out
GNU gdb (GDB) Red Hat Enterprise Linux (7.2-60.el6_4.1)
[...]
(gdb) break fsub
Breakpoint 1 at 0x400888
(gdb) run
Starting program: a.out
5
Breakpoint 1, 0x00007ffff7dfc7e4 in fsub () from ./libfmodule.so
(gdb) step
Single stepping until exit from function fsub,
which has no line number information.
stop_string (string=0x7ffff7dfc8d8 "x >=5 : this kills the programfmodule.f90", len=30) at /usr/local/src/gcc-4.7.2/libgfortran/runtime/stop.c:67
So stop_string is called. We need to know to which symbol this function corresponds.
Step 2. Find the exact name of the stop_string function. It must be in one of the shared libraries.
$ ldd ./a.out
linux-vdso.so.1 => (0x00007fff54095000)
libfmodule.so => ./libfmodule.so (0x00007fa31ab7d000)
libstdc++.so.6 => /usr/local/gcc/4.7.2/lib64/libstdc++.so.6 (0x00007fa31a875000)
libm.so.6 => /lib64/libm.so.6 (0x0000003da4000000)
libgcc_s.so.1 => /usr/local/gcc/4.7.2/lib64/libgcc_s.so.1 (0x00007fa31a643000)
libc.so.6 => /lib64/libc.so.6 (0x0000003da3c00000)
libgfortran.so.3 => /usr/local/gcc/4.7.2/lib64/libgfortran.so.3 (0x00007fa31a32f000)
libquadmath.so.0 => /usr/local/gcc/4.7.2/lib64/libquadmath.so.0 (0x00007fa31a0fa000)
/lib64/ld-linux-x86-64.so.2 (0x0000003da3800000)
I found it in (no surprise) the fortran runtime.
$ readelf -s /usr/local/gcc/4.7.2/lib64/libgfortran.so.3|grep stop_string
1121: 000000000001b320 63 FUNC GLOBAL DEFAULT 11 _gfortran_stop_string##GFORTRAN_1.0
2417: 000000000001b320 63 FUNC GLOBAL DEFAULT 11 _gfortran_stop_string
Step 3. Write a function that will replace that function
I look for the precise signature of the function in the source code (/usr/local/src/gcc-4.7.2/libgfortran/runtime/stop.c see gdb session)
$ cat my_exit.c
#define _GNU_SOURCE
#include <stdio.h>
void _gfortran_stop_string (const char *string, int len)
{
printf("Let's keep on");
}
Step 4. Compile a shared object exporting that symbol.
gcc -Wall -fPIC -c -o my_exit.o my_exit.c
gcc -shared -fPIC -Wl,-soname -Wl,libmy_exit.so -o libmy_exit.so my_exit.o
Step 5. Run the program with LD_PRELOAD so that our new function has precedence over the one form the runtime
$ LD_PRELOAD=./libmy_exit.so ./a.out
1
1.0000000000000000
2
2.0000000000000000
3
3.0000000000000000
4
4.0000000000000000
5
Let's keep on 5.0000000000000000
6
Let's keep on 6.0000000000000000
7
Let's keep on 7.0000000000000000
There you go.
Since what you want would result in non-portable code anyway, why not just subvert the exit mechanism using the obscure long jump mechanism:
#include<iostream>
#include<csetjmp>
#include<cstdlib>
// prototype for the external Fortran subroutine
extern "C" {
void fsub(double* x);
}
volatile bool please_dont_exit = false;
std::jmp_buf jenv;
static void my_exit_handler() {
if (please_dont_exit) {
std::cout << "But not yet!\n";
// Re-register ourself
std::atexit(my_exit_handler);
longjmp(jenv, 1);
}
}
void wrapped_fsub(double& x) {
please_dont_stop = true;
if (!setjmp(jenv)) {
fsub(&x);
}
please_dont_stop = false;
}
int main() {
std::atexit(my_exit_handler);
double x;
while(std::cin >> x) {
wrapped_fsub(x);
}
return 0;
}
Calling longjmp jumps right in the middle of the line with the setjmp call and setjmp returns the value passed as the second argument of longjmp. Otherwise setjmp returns 0. Sample output (OS X 10.7.4, GCC 4.7.1):
$ ./a.out
2
2.0000000000000000
6
STOP x >=5 : this kills the program
But not yet!
7
STOP x >=5 : this kills the program
But not yet!
4
4.0000000000000000
^D
$
No library preloading required (which anyway is a bit more involved on OS X than on Linux). A word of warning though - exit handlers are called in reverse order of their registration. One should be careful that no other exit handlers are registered after my_exit_handler.
Combining the two answers that use a custom _gfortran_stop_string function and longjmp, I thought that raising an exception inside the custom function would be similar, then catch in in the main code. So this came out:
main.cpp:
#include<iostream>
// prototype for the external Fortran subroutine
extern "C" {
void fsub(double& x);
}
int main() {
double x;
while(std::cin >> x) {
try { fsub(x); }
catch (int rc) { std::cout << "Fortran stopped with rc = " << rc <<std::endl; }
}
return 0;
}
catch.cpp:
extern "C" {
void _gfortran_stop_string (const char*, int);
}
void _gfortran_stop_string (const char *string, int len)
{
throw 666;
}
Then, compiling:
gfortran -c fmodule.f90
g++ -c catch.cpp
g++ main.cpp fmodule.o catch.o -lgfortran
Running:
./a.out
2
2.0000000000000000
3
3.0000000000000000
5
Fortran stopped with rc = 666
6
Fortran stopped with rc = 666
2
2.0000000000000000
3
3.0000000000000000
^D
So, seems to work :)
I suggest you fork your process before calling the fortran code and exit 0 (edit: if STOP exits with zero, you will need a sentinel exit code, clanky but does the job) after the fortran execution. That way every fortran call will finish in the same way: the same as if it had stopped. Or, if "STOP" ensure an error, throw the exception when the fortran code stops and send some other message when the fortran execution "completes" normaly.
Below is an example inspire from you code assuming a fortran "STOP" is an error.
int main() {
double x;
pid_t pid;
int exit_code_normal = //some value that is different from all STOP exit code values
while(std::cin >> x) {
pid = fork();
if(pid < 0) {
// error with the fork handle appropriately
} else if(pid == 0) {
fsub(x);
exit(exit_code_normal);
} else {
wait(&status);
if(status != exit_code_normal)
// throw your error message.
}
}
return 0;
}
The exit code could be a constant instead of a variable. I don't think it matters much.
Following a comment, it occurs that the result from the execution would be lost if it sits in the memory of the process (rather than, say, write to a file). If it is the case, I can think of 3 possibilities:
The fortran code messes a whole lot of memory during the call and letting the execution continue beyond the STOP is probably not a good idea in the first place.
The fortran code simply return some value (through it's argument if my fortran is not too rusty) and this could be relayed back to the parent easily through a shared memory space.
The execution of the fortran subroutine acts on an external system (ex: writes to a file) and no return values are expected.
In the 3rd case, my solution above works as is. I prefer it over some other suggested solution mainly because: 1) you don't have to ensure the build process is properly maintained 2) fortran "STOP" still behave as expected and 3) it requires very few lines of code and all the "fortran STOP workaround" logic sits in one single place. So in terms of long term maintenance, I much prefer that.
In the 2nd case, my code above needs small modification but still holds the advantages enumerated above at the price of minimal added complexity.
In the 1st case, you will have to mess with the fortran code no matter what.
I did a new installation of Eclipse Juno 32 bits, and a new installation of MinGW 32 bits, my platform is Windows 7 64 bits. When trying to debug a simple program I can watch very simple expressions, but everything more complicated gets me an error. For an example in the following program:
int main()
{
vector<int> vRings;
for(int i=0;i<50;i++) {
vRings.push_back(i%5);
}
//std::cout << "result:" << getRingNumber(vRings,vDiscs);
return 0;
}
In the watch window, watching vRings work normally, but trying to watch the content of the vector doesn't work:
Trying to watch vRings[0]:
Error: Multiple errors reported.\ Failed to execute MI command: -var-create - *
vRings[0] Error message from debugger back end: Could not find
operator[].\ Unable to create variable object
Trying to watch vRings.at(0):
vRings.at(0) Error: Multiple errors reported.\ Failed to execute MI
command: -var-create - * vRings.at(0) Error message from debugger back
end: Cannot evaluate function -- may be inlined\ Unable to create
variable object
What can I do to solve the problem?
You are trying to watch the result of a function call.
Both vRings.at() and vRings[] are functions (the latter an overloaded function) that return a reference to a value. In your case - an integer.
If you want to watch the value of vRings at index 0, you can try to assign it to a variable at some point, for example:
int main()
{
vector<int> vRings;
for(int i=0;i<50;i++) {
vRings.push_back(i%5);
}
int watchme = vRings.at(0);
//std::cout << "result:" << getRingNumber(vRings,vDiscs);
return 0;
}
Then you can watch the variable watchme.
I'm writing a program that takes 2 command line arguments: a and b respectively.
Everything is good as long as a <= 17.5
As soon as a > 17.5 the program throws the following error:
incorrect checksum for freed object - object was probably modified after being freed
I've narrowed down the problem down to the following piece of code:
for(int a=0; a < viBrickWall.size(); a++) {
vector<int64_t> viTmp(iK-i);
fill(viTmp.begin(),viTmp.end(),2);
for(int b = 0; b < viBrickWall[a].size(); b++) {
viTmp[viBrickWall[a][b]] = 3;
}
viResult.push_back(viTmp);
viTmp.clear();
}
Removing the latter piece of code, gets rid of the error.
I'm also using valgrind to debug the memory, but I haven't been able to find any solution.
Here it is a copy of valgrind's report:
Report hosted in pastebin
EDIT
I compiled the program with debugging flags:
g++ -g -O0 -fno-inline program.cpp
and ran it with valgrind as follows:
` valgrind --leak-check=full --show-reachable=yes --dsymutil=yes ./a.out 48 10 ``
I noticed the following line:
==15318== Invalid write of size 8
==15318== at 0x100001719: iTileBricks(int) (test.cpp:74)
==15318== by 0x100001D7D: main (test.cpp:40)
Line 74 is:
viTmp[viBrickWall[a][b]] = 3;
and Line 40 is:
viBrickWall = iTileBricks(iPanelWidth);
You're causing an invalid write to heap memory with this line:
viTmp[viBrickWall[a][b]] = 3;
this implies that viBrickWall[a][b] is indexing outside of viTmp at that time. Add
int i = viBrickWall[a][b];
assert(0 <= i && i < viTmp.size());
before the store to viTmp[i] = 3.
HINT: maybe increasing the size of viTmp by one would fix it:
-vector<int64_t> viTmp(iK-i);
+vector<int64_t> viTmp(iK - i + 1);
I don't know the content of viBrickWall so this is just an educated guess from the Valgrind output.
I'm not sure if you're using GNU libstdc++ or libc++ on Mac OSX. If you're using libstdc++ or have a Linux box handy, declare viTmp to be a std::__debug::vector would catch this problem quickly.
Last week I was a debugging a code and a weird situation came up: gdb passes through two different return clauses. I made a simple example that illustrates the situation:
#include <iostream>
using namespace std;
int test() {
string a = "asd";
string b = "asd";
while (true) {
if (a == b) {
return 0;
}
}
return -1;
}
int main() {
int result = test();
cout << "result: " << result << endl;
}
When debugging the code I got:
(gdb) b main
Breakpoint 1 at 0x1d4c: file example.cpp, line 19.
(gdb) r
Starting program: /Users/yuppienet/temp/a.out
Reading symbols for shared libraries +++. done
Breakpoint 1, main () at example.cpp:19
19 int result = test();
(gdb) s
test () at example.cpp:7
7 string a = "asd";
(gdb) n
8 string b = "asd";
(gdb) n
11 if (a == b) {
(gdb) n
12 return 0;
(gdb) n
15 return -1;
(gdb) n
16 }
(gdb) n
main () at example.cpp:20
20 cout << "result: " << result << endl;
(gdb) n
result: 0
21 }
(gdb) n
0x00001ab2 in start ()
I noted that even if gdb shows line 15, the return value is 0 (the finish command confirms this as well).
So the question is: why does gdb show line 15: return -1, even if the function is not really returning this value?
Thanks!
Edit:
I forgot to mention that I compiled with the following line:
g++ -Wall -pedantic -g -pg example.cpp
I suspect you're seeing the function epilogue. Your two strings have destructors, which are being implicitly called on return. Check out what the disassembly says to be sure, but I suspect that both return statements are mapping to something along the lines of:
stash return_value;
goto epilogue;
and correspondingly:
epilogue:
destroy a; // on the stack, so destructor will be called
destroy b;
really_return(stashed value);
The epilogue appears to come from line 15 as a side-effect of how g++ does line numbering - a fairly simple format, really just a list of tags of the form "address X comes from line number Y" - and so it's reporting 15 as the closest match. Confusing in this case, but correct a lot of the time.
Probably because the program counter register passes through the instructions that best map to the final return, i.e. the function's exit sequence. The actual return value is probably kept in a register, so the first return just loads the proper value and jumps to the end of the function, and then that address is "back-mapped" to the source code line of the final return.
You don't say, but if you compiled with optimization that is exactly the kind of behavior you would see in gdb. You see the first line setting up the return value, and then it jumps to the real return instruction but in C++ you see the entire thing including the return value.