GDB: Getting parameter values when they have no name? - c++

I'm debugging an app with GDB and when I step into a frame, I see something like this:
#2 0x00007fff4da4276b in MHWRender::THgeometryOverrideEvaluator::doDGBoundingBox(TdgContext const&, OGSMayaCompoundNode*) ()
Normally, I'd just print out parameter addresses, but in the case of the second parameter here, there's no parameter name. How do I get the info I need?

How do I get the info I need?
The output you got is indicative of the code being compiled without debug info.
The easiest fix is to add -g as appropriate and rebuild your application.
Without debug info, you can only do debugging at assembly level, which requires knowing the calling convention on your platform (which you did not specify).
Assuming this is Linux on x86_64, and assuming that doDGBoundingBox is not a static function, the first (this) parameter will be passed in $rdi, second (the TdgContext&) in $rsi, and third (the OGSMayaCompoundNode*) in $rdx. Reference.

Related

What is lldb's equivalent one of gdb's advance command?

When debugging C/C++ function that with many arguments, and each arguments may still call some functions, people have to repeated typing step and finish, then reach where this function's body part.
e.g. I'm using OpenCV's solvePnP() function, it requires many arguments:
solvePnP(v_point_3d,v_point_2d,K,D,R,T);
Among which, each argument will be converted from cv::Mat to cv::InputArray, thus calling a init() function.
What I expected is, directly go to where solvePnP() implemented, and I'm not interested in each argument type conversion.
Luckily, there is advance command in gdb. Official document is here, writes:
advance location
Continue running the program up to the given location. An argument is required, which should be of one of the forms described in Specify Location. Execution will also stop upon exit from the current stack frame. This command is similar to until, but advance will not skip over recursive function calls, and the target location doesn’t have to be in the same frame as the current one.
This gdb advance command really helps. And what's the equivalent command in LLDB?
I've search in lldb official's gdb => lldb command mapping web page, https://lldb.llvm.org/use/map.html , but not found.
Edit: I forgot to mention, the gdb usage for me is
(gdb) b main
(gdb) r
(gdb) advance solvePnP
Checkout the sif command for lldb. sif means **Step Into Function
Reference: How to step-into outermost function call in the line with LLDB?
To get all the supported commands of LLDB, one should first go into lldb command, then type help, then there will be the explanations for sif:
sif -- Step through the current block, stopping if you step directly into a function whose name matches the TargetFunctionName.

Is there a quick way to display the source code at a breakpoint in gdb?

I've set a breakpoint in gdb, and I'd like to see the exact line of source the breakpoint is on, just to confirm it's correct -- is there a quick way to do this?
The "info b" command gives me information about the breakpoints, but it doesn't display source:
(gdb) info b
Num Type Disp Enb Address What
1 breakpoint keep y 0x00000000006c3ba4 in MyClass::foo(bar*)
at /home/user1/src/MyClass.cpp:1021
I can type "list MyClass.cpp:1021" to see the lines around this breakpoint, but I'm wondering if there's a shorter way. Googling and reading the gdb manual didn't turn up anything.
I know that if I'm executing the program and have hit the breakpoint, I can just type "list", but I'm asking specifically about the case where I am not at the breakpoint (the program may not even be running).
You can use the list command to show sources. list takes a "linespec", which is gdb terminology for the kinds of arguments accepted by break. So, you can either pass it whatever argument you used to make the breakpoint in the first place (e.g., list function) or you can pass it the file and line shown by info b (e.g., list mysource.c:75).
I think the closest one can get to this is by turning the history on (set history save on) and then press CTRL-R to do a reverse search for the former list command.
More specifically, change your workflow when setting a breakpoint. After each command like b main GDB shows the source file like path/to/main.cpp, line 12. Immediately use this information in a quick list main.cpp:12. To show this location later press CTRL-R and type "main".
https://sourceware.org/gdb/onlinedocs/gdb/Command-History.html

GDB set a breakpoint at a wrong address for a template function

When I set a breakpoint in a specific template function in GDB, it shows 3 different breakpoints set (I guess this is due to template nature of the function). The addresses of 2 of them looks correct, but one is something like 0x00...0013. As a result, GDB can't continue, it complaints about wrong address. What does it mean and what can I do about it?
Not sure if this matters, but I set the breakpoint like this: b file_name.cc:line_number .
I can set a bp successfully at another template function located in a different directory.

Finding function parameters of function that is not on top of stack using windbg

Here is the part of call stack returned by kd command. I want to know what parameters were passed to myutil!myclass::somefunc. How do I get those parameters using windbg?
0a11f614 0a11f634
0a11f618 7686592c rpcrt4!Invoke+0x2a
0a11f61c 0e7b2c98
0a11f620 03edad48
0a11f624 03edaba8
0a11f628 00000206
0a11f62c 00000003
0a11f630 0a11f820
0a11f634 0a11fa38
0a11f638 768e05f1 rpcrt4!NdrStubCall2+0x2ea
0a11f63c 6dbc12b2*** WARNING: Unable to verify timestamp for myutil
myutil!myclass::somefunc
Thanks in advance,
-Neel.
about the stack being different
There is no reason that the stack shown by kd and kp would be different. They are essentially different representation on the same data.
If you paste the stack here may be we will be point out whats going on!
Are you sure you running both commands in the same place ?
how to check if symbols are loaded correctly
execute the command : "lml" to see for which binaries, symbols have been loaded.
Coming to your original question
kP is the simplest way to see the parameters that are being passed to the function.
another way to do the same thing is
a. run "kn" so that you see frame numbers in the stack trace.
b. move to the frame of interest by doing ".frame
c. now dump the variables using "dv"
If you are really passionte you can read about paramter passing. Then all you would need is the EBP + some assembly code reading to figure out which parameters we passed.

c++ - calling function by address fails

I was reading up on various things on CodeProject and I found this article: http://www.codeproject.com/Articles/29527/Reverse-Engineering-and-Function-Calling-by-Addres
So what I did was I created an injector and a DLL, and grabbed the sample executable file. It basically outputs this when you press F11:
http://i.stack.imgur.com/YIygV.jpg
So I followed the entire tutorial, but the thing is that the address used in the DLL is always changing. This one to be specific:
pFunctionAddress pMySecretFunction = (pFunctionAddress)(0x004113C0);
In his tutorial the address for the function is 0x004113C0. In mine it is something else, and I take the one I have and use it. It works perfectly, but when I close the executable and open it, it won't work anymore, and OllyDbg shows that the address is a totally new one.
So I researched a bit and I started adding breakpoints with OllyDbg. I found out that the address is always going to be:
main + 4C
Where I guess "main" is the main module of these executable. How can I find this address to the function always? Because it changes all the time and I am clueless at this point. In this article I read it doesn't go through what happens when the executable is re-opened, and I've spent 5 hours trying to find a solution.
Thanks in advance!
EDIT:
Huge thanks to everyone. Thanks to mfc especially, I have finally figured it out! What I ended up doing was whenever I hit DLL_PROCESS_ATTACH, I set a global HMODULE to the address of the executable, like this:
HMODULE g_hExeModule;
g_hExeModule = GetModuleHandle(L"TutExample.exe");
And after a few tests it seems like the function address is always the address of the executable + 0x11014, so in the call I just do:
pFunctionAddress pMySecretFunction = (pFunctionAddress)((DWORD)g_hExeModule + 0x11014);
so if I find a way to get the address of "main" I can add a 4C offset and the function will always be there, I think
Again, functions do have an address:
void *(funcPtr)() = (void (*)())((char *)&main + 0x4C);
// If you were right, and you also substituted the appropriate
// function signature above, then this should work:
funcPtr();
The function that you are trying to call is inside of the exe file, so the reference offset should be relative to the memory address that the exe is loaded.
The offset to the target function should be a constant, changed only after each compilation of the source code.
To find out more about your exe, add these two line into your exe:
printf(_T("Exe loaded at: %08X"), GetModuleHandle(_T("TutExample.exe")));
printf(_T("Target function at: %08X"), mySecretFunction);
I cannot edit my post nor add any remark, so I have to post this as a new answer.
Your result:
Exe loaded at: 00000000 (wrong, probably: 00BE0000 and offset is: 00001005)
Target function at: 00BE1005
Exe loaded at: 00000000 (wrong, probably: 01230000 and offset is: 00001005)
Target function at: 01231005
Exe loaded at: 00000000 (wrong, probably: 012A0000 and offset is: 00001005)
Target function at: 012A1005
Please check the name of your compiled exe, is it "TutExample.exe" ? if not, change it to the exact name in the call to GetModuleHandle.
The value of "00000000" indicates that the GetModuleHandle fails because the name "TutExample.exe" is not found in the current memory space.
The address of target function seems ok. Just minus this address with the address of loaded exe and you will get the offset inside the exe memory layout.
You can do this same math inside your injected dll to alway tracks the target function address correctly no matter how the os loads the exe.
Newer OS's have a feature called ASLR (Address space layout randomization). Criminals use some of the trick you are using. So to make bad guys lives more difficult, EXE and DLL's get assigned a different address every time you run a program.
If you compiled the DLL, there is an option to disable ASLR for your DLL.