I am using the Instruments to profile a very simple program. Here is the result:
result
My question is: why the heaviest back trace are annotated on a very simple line of code? I think that line only needs some ALU instructions to implement. Is this a bug or I missed something?
I see nothing unusual in the screenshot you linked to. The 99x line in your screenshot has nothing to do with the heaviness of the backtrace. It is the line of code where Instruments recorded the most samples. The 99x line is inside a loop. Code inside loops is going to execute more often and have more samples.
Related
I'm trying to profile my code using Instruments. What I get is something like the following window:
What I don't understand is: below lq_cohomology, Instruments lists HeapMatrix::pivot. This method is never called directly from lq_cohomology, but only from other functions called by lq_cohomology. Furthermore, I don't understand why `HeapMatrix::pivot shows up multiple times in the profile. Shouldn't that occur only a single time?
When I put a "pause" command into my program, I can precede it with a disp("Just finished averaging") or something of the kind, so I can read on the console which "pause" I am at.
But when I lose my patience with a program that's taking forever to complete, and hit Ctrl-C to see what is going on, I cannot see a way of finding out which code line I interrupted it at. The "whereami" command tells me I am in pause, which is obviously true but hardly helpful; it's like a GPS device telling me I'm in the driver seat. Oh yeah, I figured that myself, thank you Captain.
I am tempted to create a dedicated variable, say MyApproximateCurrentCodeLine, and updating it every few lines of code with hard-wired substitution commands. This would work but would take a lot of time to write, a similar amount of time to remove when I'm done, and would have to be repeated with every program I need to debug. Not to mention it's just plain ugly.
Is there a better way of finding the current execution point?
Once you have interrupted the program
[linenum, callername] = where()
will give you the full calling tree.
S.
I have an application that traces program execution through memory. I tried to use readelf --debug-dump=decodedline to get memory address / line # information, but the memory addresses I see don't match up often with the ones given by that dump. I wrote something to match up each address with the "most recent" one appearing in the DWARF data -- this seemed to clean some things up but I'm not sure if that's the "official" way to interpret this data.
Can someone explain the exact process to map a program address to line number using DWARF?
Have a look at the program addr2line. It can probably give you some guidance on how to do this, if not solving your problem entirely (e.g. by shelling out to it, or linking its functionality in).
Indeed, as mentioned by Phil Miller's answer, addr2line is your friend. I have a gist where I show how I get the line number in the (C++) application source code from an address obtained from a backtrace.
Following this process will not show you the process you mention, but can give you an idea of how the code gets mapped into the object code (in an executable or a library/archive). Hope it helps.
hey guys i have a question regarding amzi prolog with eclipse,
Im running a .pro file which executes a breadth first search and if queue gets too long,
the following error message appears:
system_error 1021 Control stack full.
Compile code or increase .cfg
parameter 'control'
If so, how may i run the compiled code under eclipse? I've tried running the project but the listener just ends without accepting any queries....?
Control stack full means one of two things:
You have a deep recursion that exhausts the control stack. In that case you need to increase the default value of 'control' in your amzi.cfg file. You may find you that have to increase 'heap', 'trail' and/or 'local' as well.
You have an error in your program causing an infinite recursion.
Running the program in the debugger will show you which case you've got. In the initial case you will see it digging deeper and deeper for a solution. In the later case you will see it chasing it's tail in circles with each recursion the same as the one before, but with different variables.
I don't know amzi prolog (I only used SICStus and SWI), and never used Eclipse for prolog, but as the error message says, try compiling (instead of consulting) your code. Look under project/properties for build configurations (like run/deug, as it works for Java/C++). Hopefully, that ".cfg paramerer" can also be accessed through project/properties.
Is it possible for the debugger (or the CLR exception handler) to show the line where the exception happened in Release mode using the pdb?
The code, in release mode, is optimized and do not always follow the order and logic of the "original" code.
It's also surprising that the debugger can navigate through my code step by step, even in Release mode. The optimization should make the navigation very inconfortable.
Could you please clarify those two points for me?
I'm not as familiar with how this is done with CLR, but it's probably very similar to how it's done with native code. When the compiler generates machine instructions, it adds entries to the pdb that basically say "the instruction at the current address, X, came from line 25 in foo.cpp".
The debugger knows what program address is currently executing. So it looks up some address, X, in the pdb and sees that it came from line 25 in foo.cpp. Using this, it's able to "step" through your source code.
This process is the same regardless of Debug or Release mode (provided that a pdb is generated at all in Release mode). You are right, however, that often in release mode due to optimizations the debugger won't step "linearly" through the code. It might jump around to different lines unexpectedly. This is due to the optimizer changing the order of instructions, but it doesn't change the address-to-source-line mapping, so the debugger is still able to follow it.
[#Not Sure] has it almost right. The compiler makes a best effort at identifying an appropriate line number that closely matches the current machine code instruction.
The PDB and the debugger don't know anything about optimizations; the PDB file essentially maps address locations in the machine code to source code line numbers. In optimized code, it's not always possible to match exactly an assembly instruction to a specific line of source code, so the compiler will write to the PDB the closest thing it has at hand. This might be "the source code line before", or "the source code line of the enclosing context (loop, etc)" or something else.
Regardless, the debugger essentially finds the entry in the PDB map closest (as in "before or equal") to the current IP (Instruction Pointer) and highlights that line.
Sometimes the match is not very good, and that's when you see the highlighted area jumping all over the place.
The debugger makes a best-effort guess at where the problem occurred. It is not guaranteed to be 100% accurate, and with fully optimized code, it often will be inaccurate - I've found the inaccuracies ranging anywhere from a few lines off to having an entirely wrong call stack.
How accurate the debugger is with optimized code really depends on the code itself and which optimizations you're making.
Reference the following SO question:
Display lines number in stack trace for .NET assembly in release mode