Using gdb, I have encountered a strange issue: there is a method which appears three times:
(gdb) b Logger::Logger
[0] cancel
[1] all
[2] Logger at src/Logger.cpp:52
[3] Logger at src/Logger.cpp:52
[4] Logger at src/Logger.cpp:52
From the fact that all three instances are on line 552 of the file Logger.cpp, it can be deduced, that they are in fact referring to the same method.
What is the meaning of this? Has Logger::Logger constructor accidentally got into the binary three times, or is this a gdb bug?
Recent versions of GCC (and many other compilers) create several versions of constructors and destructors.
There was a bug in GDB, where it neglected to set a breakpoint on all versions, which resulted in your breakpoint never firing at all. Now, with the GDB bug corrected, you get multiple breakpoints.
Select all, then do info break, and note that the addresses of the 3 breakpoints all differ, and are in fact in different functions.
Either the method got inlined because gcc thought it would perform better, or it was used in a template which got instantiated in more than one way. Either path could lead to multiple versions in the executable binary.
You can use "info break" and disable, enable for perhaps a breakpoint set to the same line.... however, you should also know, step vs. stepi (stepi will execute single machiene code instruction, not by source level, which is what step does).
You can also c #, to continue a specific amoutn of times, to pass that breakpoint... so if it's 1 breakpoint in a loop, which is being evaluated 3 times, you go c 3, and you will pass this perticular loop...
Related
Looking through a core file(generated by C code) with gdb, I am unable to understand one particular thing between these 2 frames
#2 increment_counter (nsteps=2, steps=0x7f3fbad26790) at gconv_db.c:393
#3 find_derivation (...) at gconv_db.c:426
This code is from open source glibc where find_derivation calls increment_counter as:
result = increment_counter (*handle, *nsteps);
The *handle and steps are of the same type and increment_counter function is defined as static
Why does gdb show that the 2 parameters have different order ?
I am pretty sure that glibc was taken as is without modification
Why does gdb show that the 2 parameters have different order ?
GDB doesn't know anything about the source (except possibly where on disk it was located at build time).
It is able to display parameters (and their values) because the compiler told it (by embedding debug info into the object file) what parameters are, in what order they appear, their types, and how to compute their value.
So why would a compiler re-order function arguments?
The function is static, so it can't be called from outside of the current translation unit. Thus the compiler is free to re-order the parameters, so long as it also re-orders the arguments at every call site.
Still, why would it do that? General answer: optimization (compiler found it more convenient to pass them in this order). Detailed answer would require digging into GCC (or whatever compiler was used to build this code) source.
For example:
dprintf main,"hello\n"
run
Generates the same output as:
break main
commands
silent
printf "hello\n"
continue
end
run
Is there a significant advantage to using dprintf over commands, e.g. it is considerably faster (if so why?), or has some different functionality?
I imagine that dprinf could be in theory faster as it could in theory compile and inject code with a mechanism analogous to the compile code GDB command.
Or is it mostly a convenience command?
Source
In the 7.9.1 source, breakpoint.c:dprintf_command, which defines dprintf, calls create_breakpoint which is also what break_command calls, so they both seem to use the same underlying mechanism.
The main difference is that dprintf passes the dprintf_breakpoint_ops structure, which has different callbacks and gets initialized at initialize_breakpoint_ops.
dprintf stores list of command strings much like that of commands command, depending on the settings. They are:
set at update_dprintf_command_list
which gets called on after a type == bp_dprintf check inside init_breakpoint_sal
which gets called by create_breakpoint.
When a breakpoint is reached:
bpstat_stop_status gets called and invokes b->ops->after_condition_true (bs); for the breakpoint reached
after_condition_true for dprintf is dprintf_after_condition_true
bpstat_do_actions_1 runs the commands
There are two main differences.
First, dprintf has some additional output modes that can be used to make it work in other ways. See help set dprintf-channel, or the manual, for more information. I think these modes are the reason that dprintf was added as a separate entity; though at the same time they are fairly specialized and unlikely to be of general interest.
More usefully, though, dprintf doesn't interfere with next. If you write a breakpoint and use commands, and then next over such a breakpoint, gdb will forget about the next and act as if you had typed continue. This is a longstanding oddity in the gdb scripting language. dprintf doesn't suffer from this problem. (If you need similar functionality from an ordinary breakpoint, you can do this from Python.)
So I've got a backtrace
Exit with signal 11 at 2013-12-28_14:28:58.000000
/opt/s3ds/App(_Z7handlers+0x52) [0x5de322]
/lib/libc.so.6(+0x32230) [0x7f6ab9b3a230]
/opt/s3ds/App(_ZN17Service17Controller5frameERKf+0x505) [0x5a6b85]
/opt/s3ds/App(_ZN17Service15Cloud10updateEf+0x1de) [0x58642e]
/opt/s3ds/App(_ZN17Manager6updateEf+0x21b) [0x59194b]
/opt/s3ds/App(_ZN7Manager3runEv+0xd2) [0x604fa2]
/opt/s3ds/App() [0x62bfea]
/lib/libpthread.so.0(+0x68ca) [0x7f6abb0048ca]
/lib/libc.so.6(clone+0x6d) [0x7f6ab9bd7b6d]
I've compiled my application with next arguments:
-std=c++11 -fpermissive -m64 -g -rdynamic -mtune=native -flto -O3
So it is a release build with some minimal debug information.
I wonder if it is possible to use addr2line to get any line number from such optimized build?
I tried example shown here yet I get ??:0 like:
$ addr2line -e ./App 0x62bfea
??:0
for all adresses in []. I know tha functions in that trace from Service::Controller::frame up to Manager::run (and probably even that lambda /opt/s3ds/App() [0x62bfea]) shall be in my app code (not in some library).
So Is it possible to get line numbers for production optimized code? Are there any additional compiler argiments required to get them?
It may be possible, but it might not amount to much.
You have to understand that the very goal of optimizations is to alter the code to make it better (by some metric); and alteration means that the resulting code may not be meaningfully mapped to source code afterwards.
Some examples:
Dead Code Elimination and the like will remove existing code, this mainly affect an attempt to place a breakpoint at a given source-line since there may not be code for that line
Common Sub-Expression Elimination will create new temporary variables out of the blue to compute a sub-expression only once; those sub-expressions may have originally appeared in multiple expressions spread throughout the source code so the new instructions belong to multiple lines... or none at all
Invariant Hoisting or Loop Rotation will change the order in which expressions are computed compared with the original source code so that you might see code executed at line 3 then 6 then 4, 5, 7...
Loop Unrolling will copy/paste the body of a loop multiple times
And of course, those are local to a function, you also to have to account for
Function Inlining will copy paste the body of a function at the call site
Function Merging will take two different functions and remove one of them, forwarding its calls to the other (because they have the same behavior, of course)
After all that, is it even meaningful to try and reason in terms of source code ? No, not really. And of course I did not even account for the fact that all those transformations occurred on the Intermediate Representation and that the final emission of assembly code will scramble things even further (Strength Reduction, yeah!).
Honestly, even if addr2line gives you some line, I would doubt its result... and then what is the point of asking in the first place ?
I'm not sure. Normally, the rdynamic switch should be sufficient when the function is part of your own code (which seem to be the case, in your example)
Have you tried to compile with -fno-inline-functions -fno-inline-functions-called-once -fno-optimize-sibling-calls? It is useful when you profiling an optimized program. Maybe it can also help to solve your problem.
(Side note: Calling addr2line with the -C switch activates demangling, which is recommended since you are using C++.)
0x004069f1 in Space::setPosition (this=0x77733cee, x=-65, y=-49) at space.h:44
0x00402679 in Checkers::make_move (this=0x28cbb8, move=...) at checkers.cc:351
0x00403fd2 in main_savitch_14::game::make_computer_move (this=0x28cbb8) at game.cc:153
0x00403b70 in main_savitch_14::game::play (this=0x28cbb8) at game.cc:33
0x004015fb in _fu0___ZSt4cout () at checkers.cc:96
0x004042a7 in main () at main.cc:34
Hello, I am coding a game for a class and I am running into a segfault. The checker pieces are held in a two dimensional array, so the offending bit appears to be invalid x/y for the array. The moves are passed as strings, which are converted to integers, thus for the x and y were somehow ASCII NULL. I noticed that in the function call make_move it says move=...
Why does it say move=...? Also, any other quick tips of solving a segfault? I am kind of new to GDB.
Basically, the backtrace is trace of the calls that lead to the crash. In this case:
game::play called game::make_computer_move which called Checkers::make_move which called Space::setPosition which crashed in line 44 in file space.h.
Taking a look at this backtrace, it looks like you passed -65 and -49 to Space::setPosition, which if they happen to be invalid coordinates (sure look suspicious to me being negative and all). Then you should look in the calling functions to see why they have the values that they do and correct them.
I would suggest using assert liberally in the code to enforce contracts, pretty much any time you can say "this parameter or variable should only have values which meet certain criteria", then you should assert that it is the case.
A common example is if I have a function which takes a pointer (or more likely smart pointer) which is not allowed to be NULL. I'll have the first line of the function assert(p);. If a NULL pointer is ever passed, I know right away and can investigate.
Finally, run the application in gdb, when it crashes. Type up to inspect the calling stack frame and see what the variables looked like: (you can usually write things like print x in the console). likewise, down will move down the call stack if you need to as well.
As for SEGFAULT, I would recommend runnning the application in valgrind. If you compile with debugging information -g, then it often can tell you the line of code that is causing the error (and can even catch errors that for unfortunate reasons don't crash right away).
I am not allowed to comment, but just wanted to reply for anyone looking more recently on the issue trying to find where the variables become (-65, -49). If you are getting a segfault you can get a core dump. Here is a pretty good source for making sure you can set up gdb to get a core dump. Then you can open your core file with gdb:
gdb -c myCoreFile
Then set a breakpoint on your function call you'd like to step into:
b MyClass::myFunctionCall
Then step through with next or step to maneuver through lines of code:
step
or
next
When you are at a place in your code that you'd like to evaluate a variable you can print it:
p myVariable
or you can print all arguments:
info args
I hope this helps someone else looking to debug!
I have found myself in this situation many times where I need to break into a function that is called hundreds of times only after a particular break-point has been hit.
So let's say there is a function that updates the status of objects. This is called multiple times per
frame. I am testing a function that edits an object. As soon as that function is hit, I can then break into the UpdateStatus function. Obviously, if I put a breakpoint in UpdateStatus it will always break and I will never be able to interact with the program. What would be great if I could set a condition on the breakpoint to only break if the breakpoint in the other function hit. Note that this is just an example.
I am using Visual C++ 2008.
I remember running into a situation like this myself. I believe you can combine Visual Studio tracepoints with Visual Studio macros to do this pretty easily. This page describes how to write a macro that turns on breakpoints: http://weseetips.com/tag/enable-breakpoint/ Since you want to enable only a single breakpoint, you'll want to use some combination of file and line number in your macro to enable only the breakpoint you want--you can find the breakpoint object members here: http://msdn.microsoft.com/en-us/library/envdte.breakpoint.aspx (File and FileLine look particularly useful)
This page describes how to use a 'tracepoint' to run a macro: http://msdn.microsoft.com/en-us/library/232dxah7.aspx (This page has some nice screenshots of setting up tracepoints: http://weblogs.asp.net/scottgu/archive/2010/08/18/debugging-tips-with-visual-studio-2010.aspx in VS2010)
So you could create a macro that will enable your breakpoint, and create a tracepoint that executes your macro. (You can even add a second tracepoint that disables the breakpoint afterward, so that you can easily repeat the process.)
You might be able to place a conditional breakpoint within the UpdateStatus itself.
Alternatively, place a conditional breakpoint at the call-site of UpdateStatus then perform the step-in manually.
Whether you'll be able to do one or the other (or any at all) depends on how complex the breakpoint condition is and whether input for that condition is "reachable" from the particular stack frame.
You could have the first breakpoint set a flag when hit, then let the second breakpoint check that flag as a condition.
You can set the flag by specifying a "message" to be printed when hit, like so:
{flag = 1;}
flag needs to exist in the scope, of course.
(It would be nice if it was possible to declare a variable that only exists during the debug, but I'm unaware of how to do this.)