Using gdb, I can put a breakpoint anywhere a function is called, and step through the function evaluation. I can also evaluate a function with the print command. When stopped at any breakpoint, I would like to debug a specific function by stepping through its execution using different arguments. However, when I try to set a breakpoint at the function and give gdb a suitable print command, gdb objects with the message "The program being debugged stopped while in a function called by gdb. Evaluation of the expression containing the function MyClass::mysize(int,int) will be abandoned". Is there any way to accomplish this without restarting the program?
You managed to miss part of the message from GDB. Here is my sample program:
int
foo (int arg)
{
return arg + 3;
}
int
main ()
{
return foo (-3);
}
And here is my GDB session:
(gdb) start
Temporary breakpoint 1 at 0x401119: file eval.c, line 10.
Starting program: eval.x
Temporary breakpoint 1, main () at eval.c:10
10 return foo (-3);
(gdb) break foo
Breakpoint 2 at 0x40110d: file eval.c, line 4.
(gdb) print foo (2)
Breakpoint 2, foo (arg=2) at eval.c:4
4 return arg + 3;
The program being debugged stopped while in a function called from GDB.
Evaluation of the expression containing the function
(foo) will be abandoned.
When the function is done executing, GDB will silently stop.
(gdb) bt
#0 foo (arg=2) at eval.c:4
#1 <function called from gdb>
#2 main () at eval.c:10
(gdb)
Notice the last line of the message from GDB: When the function is done executing, GDB will silently stop. So GDB is still inside the called function with the arguments you passed. The can be seen in the backtrace with <function called from GDB>.
So you can continue stepping through the function to see how it behaves. What you don't get is the printing of the result when the function returns, GDB has lost track of the fact that this is what you wanted, so instead, when the function returns GDB will just drop you back to the prompt. What this means is that you should inspect the return value inside the function before it returns.
Related
What is main difference between trace into and step over in turbo c++
Let's say you have the following program:
void main(String[] args){
myFunc(); //breakpoint here
}
void myFunc() {
funcTwo();
}
void funcTwo() {
int x = 2;
}
If you select Step Over, the debugger will run myFunc and since there is no next line in the main function, it will end. So you will not see this a break at this line int x = 2;. After pressing F8 you will not even see a variable x, because it will just be run not debugged. The debugger sticks to the context of your main where you are debugging and not go deeper.
By selecting Trace Into, the debugger will try to run myFunc, it will see that when running that line, there are other lines of code inside. It will go deeper until it finds a line of instruction that needs to be run. This allows you to debug myFunc and funcTwo and variable x at the same time as your full application.
In my app, I'm getting a SIGSEGV fault after trying to access a field inside a widget pointer. That widget comes from a 3rd-party library. I know exactly the point where the signal is being thrown. What I want to know, is if in that specific moment, the "this" pointer of the faulty widget has been deleted or not, and when that happened.
So, the idea is to set a breakpoint at a place where I know my object does exist, and, and here is where my question borns, say to gdb: "break when the destructor of this specific "this" pointer is called". How can I tell gdb to do that?
In such a case, a can know if the object is deleted before the signal is thrown, and where and why that object has been deleted (to fix the situation).
How can I tell gdb to do that?
Use conditional breakpoint. Example:
cat -n t.cc
1 struct Foo {
2 ~Foo() {}
3 };
4
5 Foo *af1, *af2;
6 int main()
7 {
8 Foo f1;
9 af1 = &f1;
10 {
11 Foo f2;
12 af2 = &f2;
13 }
14 }
g++ -g t.cc && gdb -q ./a.out
(gdb) b 12
Breakpoint 1 at 0x400500: file t.cc, line 12.
(gdb) r
Starting program: /tmp/a.out
Breakpoint 1, main () at t.cc:12
12 af2 = &f2;
(gdb) p &f2
$1 = (Foo *) 0x7fffffffdc9f
(gdb) p &f1
$2 = (Foo *) 0x7fffffffdc9e
(gdb) b 'Foo::~Foo()' if this == 0x7fffffffdc9f
Breakpoint 2 at 0x400532: file t.cc, line 2.
(gdb) c
Continuing.
Breakpoint 2, Foo::~Foo (this=0x7fffffffdc9f, __in_chrg=<optimized out>) at t.cc:2
2 ~Foo() {}
(gdb) bt
#0 Foo::~Foo (this=0x7fffffffdc9f, __in_chrg=<optimized out>) at t.cc:2
#1 0x0000000000400517 in main () at t.cc:12
(gdb) c
Continuing.
[Inferior 1 (process 121877) exited normally]
Voila: breakpoint was hit when f2 was destructed, but not when f1 was.
My program crashes before main() function. I determine this using "cerr":
int main(int argc, char **argv)
{
cerr << " MAAIN " << endl;
The message from gdb:
Reading symbols for shared libraries ...........+++............................ done
CA(34652) malloc: *** error for object 0x7fff76694860: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Program received signal SIGABRT, Aborted.
0x00007fff88e1782a in __kill ()
(gdb) bt
#0 0x00007fff88e1782a in __kill ()
#1 0x00007fff8c4d2a9c in abort ()
#2 0x00007fff8c53184c in free ()
#3 0x00000001026a1db0 in std::basic_stringbuf<char, std::char_traits<char>, std::allocator<char> >::overflow ()
(gdb)
I have checked the code for "delete" and "free" functions. All deletes are done with check like this:
if (x) delete x;
Please help me with answering two questions:
1. What can be the possible problem?
2. How to find it? (I have a big code with a lot of files and cmake for compilation).
P.S. I read Is there any way a C/C++ program can crash before main()? but looking at gdb massage I suppose libraries are ok.
cout is not a good way to check where your program is crashing because cout does not immediately flush its buffer and it is possible that you programs crashes after cout but before flushing buffer. it's better to check it with cerr instead of cout
And before main function, constructors of global variables will call. so take look at them if you think it crashes before start.
an other possibility is allocating memory for arrays in you main function that happens before calling of main function. if they are huge. you must use new to allocate memory for them.
std::basic_stringbuf<char, std::char_traits<char>... tells me that it's std::string that is going wrong. One quite possible scenario is that you have something that is trying to "free" a string, that hasn't been constructed correctly or that has been overwritten by uncareful use of arrays.
Or you are relying on some global variables in different source files, so you have something like this:
// main.cpp:
...
extern string str; // str lives in another .cpp file
....
myclass x(str); // Construction using str.
// otherfile.cpp
string str("foobar");
In this case, str may not be constructed by the time x is being constructed, and the string is "invalid".
There are oodles of other possibilities along similar lines.
The address here: 0x7fff76694860 is on the stack. If it's always the same value, you could try to track down where it is.
My main cpp file is as:
class UnifiedDirListQuery : public UnifiedQuery{
public:
UnifiedDirListQuery(){
//do something-------------line 12
}
}
//other code
int main( void ){
UnifiedQuery *query = new UnifiedDirListQuery();//-----line 56
//do something
delete query;
}
And the UnifiedQuery is declared and defined in unified.h and unified.cpp respectively. When I debug this program in gdb:
gdb: b 56
gdb: r
gdb: s
the program jumped to line 12. How to go to unified.cpp and jump to the Ctor of base class UnifiedQuery if the ctor is defined in unified.cpp : line 25 for instance.
UPDATES
For the answer break UnifiedDirListQuery::UnifiedDirListQuery the gdb complains that:
(gdb) b UnifiedDirListQuery::UnifiedDirListQuery
[0] cancel
[1] all
?HERE
?HERE
> 1
Note: breakpoint -1 (disabled) also set at pc 0x0.
Breakpoint 1 at 0x0
Note: breakpoints -1 (disabled) and 1 also set at pc 0x0.
Breakpoint 2 at 0x0
warning: Multiple breakpoints were set.
Use the "delete" command to delete unwanted breakpoints.
(gdb) r
Starting program: /...(the path)/src/base/unified_album_list.cgi
Warning:
Cannot insert breakpoint 1.
Error accessing memory address 0x0: Input/output error.
For the answer b file:line, gdb just ignore it and went through the program without stop. BTW: actually the definition of the ctor is in a file named unified.h, implicity declared as an inline function since it is in a header file.
You can also
break UnifiedDirListQuery::UnifiedDirListQuery
Notice also that gdb has tab completion, so you don't have to type everything.
break unified.cpp:25 should do the trick, to break at line 25 for example
Especially if you have more than one file, you must give the name of the file where you want to break. See here for more information
There are two stacks in the program: one is created by OS and the second is created by program itself to run some code with it.
When the program crashes in the second stack, I want to switch to the main stack in gdb and see the backtrace. Is it possible?
I tried to save the rsp to a variable and change it after the crash, but the resulting backtrace was not right. I think gdb cannot differentiate frames in stack.
I think you were right with the approach of just restoring some register values to point GDB at the right stack. It's difficult to know how your application may have worked without any of its source, but for the very simple make/swapcontext application below:
#include <stdio.h>
#include <ucontext.h>
#include <unistd.h>
ucontext_t a_ctx, b_ctx;
char b_stack[4096];
void a2() {
swapcontext(&a_ctx, &b_ctx);
}
void a1() { a2(); }
void b2() {
printf("pausing");
pause(); // interrupt here in the debugger
}
void b1() { b2(); }
int main() {
getcontext(&b_ctx);
b_ctx.uc_stack.ss_sp = b_stack;
b_ctx.uc_stack.ss_size = sizeof(b_stack);
makecontext(&b_ctx, b1, 0);
a1();
}
The set $... command can set registers to their saved values from within GDB at which point bt will find the old stack.
(gdb) bt
#0 0x00007ffff7e8cc23 in __libc_pause () at ../sysdeps/unix/sysv/linux/pause.c:29
#1 0x00005555555551c7 in b2 () at src/so.c:16
#2 0x00005555555551d8 in b1 () at src/so.c:19
#3 0x00007ffff7e13a60 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#4 0x0000000000000000 in ?? ()
(gdb) set $rbp = a_ctx.uc_mcontext.gregs[REG_RBP]
(gdb) set $rip = a_ctx.uc_mcontext.gregs[REG_RIP]
(gdb) set $rsp = a_ctx.uc_mcontext.gregs[REG_RSP]
(gdb) bt
#0 a2 () at src/so.c:10
#1 0x00005555555551a7 in a1 () at src/so.c:12
#2 0x0000555555555234 in main () at src/so.c:26
If you have two threads with two stacks you can query the thread by 'info threads'.
After you know which thread's stack you want to see select it with the 'thread' command. Put the number of the thread after the command.
Then you only need to query the stack by 'bt'