Find the function that calculated a variable in GDB - c++

In debug mode using gdb, I can see that a function is consuming a variable, called h. I would like to know which gdb command to use to find the location (i.e. declaration of the variable or definition of another function calculating the variable) in the source code where h is calculated before being consumed by the said (second) function.
(gdb) p h
$1 = 2.556769473467e+33
(gdb) "a command to show the function that calculated h"

Related

GDB define command: print $arg1 doesn't print the correct value when in define

I want to define a new command which basically sets a breakpoint on a line, print a value of a certain variable and then continues execution. Unfortunately I am having issues. Here is the code I am using
(gdb) define print_and_continue
Type commands for definition of "print_and_continue".
End with a line saying just "end".
>break $arg0
>command $bpnum
>print $arg1
>continue
>end
>end
So I want to print the value of variable len which is defined in linked_list.h:109. And I execute the following code:
(gdb) print_and_continue linked_list.h:111 len
Breakpoint 1 at 0x388a: linked_list.h:111. (12 locations)
(gdb) r
...
Breakpoint 1, linked_list<test_struct<1>, 1>::remove_if<run_test<1, 1, 1>(std::vector<int, std::allocator<int> >&)::{lambda(test_struct<1> const&)#1}>(run_test<1, 1, 1>(std::vector<int, std::allocator<int> >&)::{lambda(test_struct<1> const&)#1}&&) (this=0x7fffffffdca0, condition=...) at linked_list.h:112
112 linked_list_node* prev = nullptr;
$1 = void
It seems like $arg1 in print function didn't get replaces by the actual argument. What am I doing wrong?
It seems like $arg1 in print function didn't get replaces by the actual argument.
I don't believe that's what is actually happening. Rather, everything following command $bpnum is attached to the newly-created breakpoint literally (without any expansion at all). You can see that happening with info break, which will show something like:
Num Type Disp Enb Address What
1 breakpoint keep y 0x0000000000001136 at ...
print $arg1
continue
This is generally what you would want (deferring evaluating the argument until the time breakpoint is hit). Otherwise you would print current value of len if you use print len, when what you want is to print the value of len when the breakpoint is hit.
Of course, when the breakpoint is hit, there is no $arg1 (or $arg0) anywhere around, so you get the same output you'd get trying to print any other non-existent GDB variable.
What am I doing wrong?
You are using "quick hack of a language" (which is what the "native" GDB scripting language is), instead of using a proper programming language.
I am 99.99% certain that defining print_and_continue is possible (and probably quite easy) using embedded Python.
That said, I don't believe that print_and_continue is all that useful (in my 20+ years of using GDB, I never needed anything like that).

gdb "Couldn't find method ..." (Method from a library)

I compiled my code only with -g flag. I have this exact expression in my code:
auto b = some_func(row[0].as<MyType>());
But when I want to inspect part of the expression:
(gdb) print row[0].as<MyType>()
Couldn't find method pqxx::field::as<MyType>
I get this error. Even though I run it in the debugger when in the same block of code the whole expression is.
(the library in which the method resides is a C++ PostgreSQL libpqxx.so)
(gdb 8.3)
That's not the only thing that doesn't work. When I do:
(gdb) print my_unordered_map.find(MyType(1))
A syntax error in expression, near `1))'.
Or:
(gdb) print my_unordered_map.find(my_lambda(row[0]))
Invalid data type for function to be called.
(also for just my_lambda(row[0])) Even though exactly this was compiled.

How to check current breakpoint function in TRACE32?

I'm trying to check if the program stopped in a function in a TRACE32.
I know I can see the the functions in FRAME window but no idea how to copy them to a variable inside my script.
Any idea how to do that ?
You get the name of the function, where the program counter points to with:
PRINT sYmbol.FUNCTION(PP())
(Instead of printing the result you can also assign it to a macro.)
So one approach to check if you've stopped in function myFunc() would be:
PRINT STRing.ComPare(sYmbol.FUNCTION(PP()),"*\myFunc")
Another way is to check if the program counter is inside the first and last address of your function myFunc():
PRINT (ADDRESS.OFFSET(sYmbol.BEGIN(`myFunc`))<=Register(PP))&&(Register(PP)<=ADDRESS.OFFSET(sYmbol.END(`myFunc`)))

gdb: print doesn't recognize variables with non-standard names or characters?

I'm writing a little BASIC compiler using LLVM, everything works fine. I'm trying to get debugging to work, and it's going fine, but I have a weird issue with variable names and GDB's print statement.
A little background on BASIC for those not familiar:
In BASIC, variable names use a symbol on the end to determine their type. So a variable x% would be integer, and variable x$ would be a string, and both can co-exist.
The statement DEFINT A-Z means that any variable starting with any letter from A to Z will be type INT, even without the trailing %. But, internally, my compiler will store the name mangled with the trailing % to avoid overlap with another variable with a trailing $.
Here is my little test program:
defint a-z
x = 5
y = 100
z = x + y
if x = 5 then
print "z=";z
else
print "z!=";z
end if
So 'x' is actually stored internally and put into the symbol table as x%.
OK, so I load my compiled EXE into GDB...
D:\dev\BasicParser>gdb t.exe
GNU gdb (GDB) 7.4
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-pc-mingw32".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from D:\dev\BasicParser\t.exe...done.
(gdb) b _jbc_main
Breakpoint 1 at 0x401000: file t.bas, line 1.
(gdb) r
Starting program: D:\dev\BasicParser\t.exe
[New Thread 1532.0x25b8]
Breakpoint 1, _jbc_main () at t.bas:1
1 defint a-z
(gdb) n
4 x = 5
(gdb) info address x%
Symbol "x%" is static storage at address 0x4263c4.
At this point, you can see that GDB recognizes the symbol x% because it recognizes and display it's address. But the following "print" fails:
(gdb) print x%
No symbol "x" in current context.
Hmmm... that's interesting ... it dropped the % symbol.
But I can look at the memory location where x% is stored and this looks correct:
(gdb) x 0x4263c4
0x4263c4 <x%>: 0x00000000
If I show all symbols I get this as expected:
(gdb) info variables
All defined variables:
File t.bas:
static i32 x%;
static i32 y%;
static i32 z%;
Continuing on, to show that x% does get modified by the code:
(gdb) n
5 y = 100
(gdb) print x%
No symbol "x" in current context.
(gdb) x 0x4263c4
0x4263c4 <x%>: 0x00000005
(gdb)
And as you can see, the memory that GDB thinks x% is at is definitely updated.
For some reason, the "print" command doesn't like the % symbol.
Here is the "info source" results on this module, you can see I didn't specify C as the language:
(gdb) info source
Current source file is t.bas
Compilation directory is D:\dev\BasicParser
Located in D:\dev\BasicParser\t.bas
Contains 18 lines.
Source language is minimal.
Compiled with DWARF 2 debugging format.
Does not include preprocessor macro info.
Any ideas for workarounds? I've been searching and searching and can't find a solution.
Thanks!
gdb simply interprets your command as modulo operation. It is not an error in gdb.
See, info source shows minimal for your file. This is from gdb's doc: http://sourceware.org/gdb/current/onlinedocs/gdb/Unsupported-Languages.html#Unsupported-Languages
In addition to the other fully-supported programming languages, GDB
also provides a pseudo-language, called minimal. It does not represent
a real programming language, but provides a set of capabilities close
to what the C or assembly languages provide.
So, what does this warning in your debugging session mean?
(gdb) print x%
No symbol "x" in current context.
Since minimal is a set of capabilities close C then gdb must iterpret this as trying to get remainder of division (http://en.wikipedia.org/wiki/Modulo_operation) - according to C programming language rules. So x is left arg, % is operation and the right arg is missing.
Let me show you example. This is a test C++ program that shows the minimal debugging session:
D:\src-c++\tests\test.vars>cat minimal.cpp
int main()
{
int k;
k = 1;
k = 2;
return 0;
}
And this is a debugging session:
D:\src-c++\tests\test.vars>gdb -q minimal.exe
Reading symbols from D:\src-c++\tests\test.vars\minimal.exe...done.
(gdb) start
Temporary breakpoint 1 at 0x4016be: file minimal.cpp, line 5.
Starting program: D:\src-c++\tests\test.vars/minimal.exe
[New Thread 2872.0x8c0]
Temporary breakpoint 1, main () at minimal.cpp:5
5 k = 1;
(gdb) show language
The current source language is "auto; currently c++".
(gdb) set language minimal
Warning: the current language does not match this frame.
(gdb) show language
The current source language is "minimal".
Warning: the current language does not match this frame.
(gdb) n
6 k = 2;
(gdb) print k
$1 = 1
(gdb) print k%
A syntax error in expression, near `'.
(gdb) print kk%
No symbol "kk" in current context.
Look -- No symbol "kk" in current context, the same error that you have.
Just a cross-reference, in case anybody else like me that might need help with this: I found this answer
In GDB, how to print the content of a symbol which has special characters?
where they indicate that you can quote names by starting with ampersand (&) and quote the name with single ticks ('), that is use something like
p &'my#complex.symbol%name'
x &'my#complex.symbol%name'
to inspect symbols with names beyond the usual C-style naming convention. I'm not completely clear what characters you can use at that point, but it seems like a good improvement.
As the other answer also points out, the GDB manual often refers to escaping symbol names just using single ticks (say something like p 'foo.c'). After some further reading I found in the GDB manual that this use of & seems to be an extension added for Windows support (see section titled "Features for Debugging MS Windows PE Executables", numbered 21.1.4 in the current edition), so I'm not sure if this may work outside of the Windows environment

gdb and current function stack

so I know that my current block is between epb and esp
is there a way to print my stack the following way:
lets says that len=ebp-esp
I would like a command on gdb that would look like this
x/lenx $esp
so I'm priting what's on the stack for the current function being executed?
can I do this using display like:
display/lenx $esp ?
is it possible to have a variable that will change each time
Seems display doesn't allow this. So you can define your own command and simply call it when you need to see a function stack:
define display_stack
eval "x /%dbx $esp", $ebp-$esp
end
And then while debugging your program:
(gdb) display_stack
If you need to see your function stack on each step you can 1) define another command nn and use it when you debug your functions 2) use hook for the pseudo-command, ‘stop’ :
define nn
n
display_stack
end
define hook-stop
echo "hook-stop, display_stack:\n"
display_stack
end
Useful links:
http://sourceware.org/gdb/onlinedocs/gdb/Define.html
http://sourceware.org/gdb/onlinedocs/gdb/Output.html#index-eval-1736
http://sourceware.org/gdb/onlinedocs/gdb/Hooks.html