how to return to main function in gdb - c

I'm using gdb for debugging
I get a segmentation fault, and then I want to set another break point in the main function and run the program from the beginning
however, although I have finished the current run
and it shows "THe program is not being run"
when I input 'list'
it shows a code snippet of a libarary file
it means currently I'm not in the main function
If I re-run the program, even if I set the break point at the beginning of the main()
it still get segmentation fault, it means the program is running within the library file
so how to return to the main() function?
thanks!
tips: I'm using libpcap.h and I have a '-lpcap' option when compiling
BTW, when I use break 9
to set a breakpoint at 9, gdb runs the program to the 11-th line? what is wrong with this inaccuracy? thanks!

Simply re-issue the run command. You will lose program state, but not breakpoints which seems to match what you need.

"BTW, when I use break 9 to set a breakpoint at 9, gdb runs the program to the 11-th line" - from this, and other information you've provided, it sounds like perhaps the source code is out of sync with gdb's mapping of addresses to source lines. Have you by any chance been editing the program? Have you recompiled it and restarted gdb? Have you seen any warnings similar to "executable is more recent than source"?

If I re-run the program, even if I set the break point at the
beginning of the main() it still get segmentation fault, it means the
program is running within the library file
Actually it means that you either failed to set breakpoint on main function or program execution not reaches main and gets segmentation fault. Try the following steps:
Rebuild program from scratch with debug info (-g gcc option). Reset breakpoint and watch for any warnings from gdb.
If program still crashes with breakpoint set on main look at stack trace (bt command in gdb). It is probably happening before main and you will not see main in stack trace.

Related

Does lldb automatically terminate an infinite loop?

I wrote an infinite loop like the following
for (size_t i = words-1; i >= 0; --i) {
... data[i] ...
}
and it would also access OOB memory. The executable crashes with a coredump. Using gdb with the coredump shows me it crashes when i is a huge number.
However, lldb can successfully run the same executable w/o any crash... Did LLDB 'interpret' the code and fix the issue for me?
No, that would be a horrible thing for a debugger to do! Debuggers in general, and lldb in particular, try hard to run your program as closely as possible to how it runs normally. There are a couple of intrusive jobs the debugger has to do when running "flat out" - e.g. it has to pause when there are shared library loads to read in the new libraries, and the debugger gets first crack at signals sent to the program. So particularly in multi-threaded programs the debugger might perturb timings. But it should never change the instruction flow of code in your program.
If you can make up a test case showing a crash when run in command line but not in lldb, please file a bug with the lldb bug tracker:
https://bugs.llvm.org
and include the example.

GDB - show last n lines executed

Sometimes in GDB I want to see the control flow that got the program to where it is now. Simply put, how do I make GDB print the last x lines executed?
This is yet another use case for Reverse Debugging.
You should start process record and replay at some point:
(gdb) record
When you want to see last executed lines you can go backwards like
this:
(gdb) reverse-step 3
or
(gdb) reverse-next 3
Use this answer https://stackoverflow.com/a/1545732/72178 to actually
print the next N executed lines.
You simply cannot do that (easily) in gdb, because the execution trace of any program is not kept (and keeping it would be very expensive : it would slow down a lot the execution, and it would use a lot of resources - memory & disk space).
You can however use the backtrace or bt command of gdb to show the call stack, that is the current instruction pointer in the current function, the calling function, the calling function of the calling function, and so forth
BTW, if you really wanted it, you might script recent gdb using Python or Guile to give you such information. You certainly could keep the entire trace (by scripting around the step & backtrace functionalities).

How to force a program compiled with '-pg' dump its stat info when it is still running?

I'm developing in C++(g++) with a non-opensource lib.
every time I run the program, the lib will crash (it double-free some memory).
it's ok for my program now. but it's bad for profiling. I use -pg to profiling the program. As a result of the crash, no 'gmon.out' is generated. so I cannot profile it at all.
Question:
How to profiling a 'crashy' program (with gprof).
PS. valgrind is ok to analysis a crashy program.
regards!
There's a function you can call from your program to dump profile data (the same one that's automatically installed as an atexit handler when you link with -pg), but I don't know what it's called offhand.
The easyist thing to do it, just insert an exit(0); call at a suitable point in your program. Alternatively, you can set a breakpoint and use call exit(0) in GDB (except that debugging the program will affect the profile data if you stop it in the middle).

Stepping into swapcontext() with gdb

I'm doing a project that makes unix system calls. To be specific, my project heavily relies of calls to getcontext(), makecontext(), swapcontext() and setcontext(). I tried to debug my code using gdb. I stepped into the code line by line and examined the control but once a call to swapcontext() is made, it doesn't step into the code anymore. Instead, debugging almost stops there and the rest of the program is run automatically instead of line by line. I guess gdb does not go into context calls? Is there any way to get around this? Is there a debugger that i can use for this?
Thanks
setcontext and swapcontext calls change the program's stack, and gdb gets confused. I do not know whether some other debugger can handle it nicely.
gdb steps through one thread and calls this the current thread. Other threads will run as you are doing this. If you set a breakpoint that gets hit in a thread other than the current thread then gdb will change the current thread to that thread. Stepping is now relative to the new current thread.
Stepping with gdb over calls of swapcontext() with 'step' or 'next' does not work because not only the stackpointer changes but also the call returns to a different code line (which is the desired effect of swapcontext()). As gdb puts a breakpoint in the next code line which will not be executed until another swapcontext() returns to this place the execution will not break.
You need to foresee the line to which swapcontext() will return and set a breakpoint there. For a new (unused) context this will be the line you specified as entry function. For used contexts it will probably one of the lines after a swapcontext() there...
You can repeatedly use GDB's stepi command to first step into and then step through the swapcontext() function. You must step several dozen times, including a few steps over kernel system calls—I presume to save the floating point state?—and you'll eventually come out in the user thread you're swapping to. It's a tad time-consuming, but it works.
As much as you may not like this answer, the best bet is to step through your code in small chunks by hand. Threaded programs don't play very well with debuggers like GDB and Valgrind (at least in my experience) and most bugs can be determined by a careful step-by-step manual analysis of the code.

fatal error disappeared when running with gdb

I have a program which produces a fatal error with a testcase, and I can locate the problem by reading the log and the stack trace of the fatal - it turns out that there is a read operation upon a null pointer.
But when I try to attach gdb to it and set a breakpoint around the suspicious code, the null pointer just cannot be observed! The program works smoothly without any error.
This is a single-process, single-thread program, I didn't experience this kind of thing before. Can anyone give me some comments? Thanks.
Appended: I also tried to call pause() syscall before the fatal-trigger code, and expected to make the program sleep before fatal point and then attach the gdb on it on-the-fly, sadly, no fatal occurred.
It's only guesswork without looking at the code, but debuggers sometimes do this:
They initialize certain stuff for you
The timing of the operations is changed
I don't have a quote on GDB, but I do have one on valgrind (granted the two do wildly different things..)
My program crashes normally, but doesn't under Valgrind, or vice versa. What's happening?
When a program runs under Valgrind,
its environment is slightly different
to when it runs natively. For example,
the memory layout is different, and
the way that threads are scheduled is
different.
Same would go for GDB.
Most of the time this doesn't make any
difference, but it can, particularly
if your program is buggy.
So the true problem is likely in your program.
There can be several things happening.. The timing of the application can be changed, so if it's a multi threaded application it is possible that you for example first set the ready flag and then copy the data into the buffer, without debugger attached the other thread might access the buffer before the buffer is filled or some pointer is set.
It's could also be possible that some application has anti-debug functionality. Maybe the piece of code is never touched when running inside a debugger.
One way to analyze it is with a core dump. Which you can create by ulimit -c unlimited then start the application and when the core is dumped you could load it into gdb with gdb ./application ./core You can find a useful write-up here: http://www.ffnn.nl/pages/articles/linux/gdb-gnu-debugger-intro.php
If it is an invalid read on a pointer, then unpredictable behaviour is possible. Since you already know what is causing the fault, you should get rid of it asap. In general, expect the unexpected when dealing with faulty pointer operations.

Resources