I am attempting to create a GDB user-defined command.
def decodecs
if $argc == 1
set $lowaddr=(short*)($arg0)
x /h $lowaddr
# The line below generates the error
set $lowaddr=$lowaddr & (short)0xfff8
x /h $lowaddr
set $lowaddr=$lowaddr >> (short)3
set $highaddr = (short*)($arg0+2)
x /h $highaddr
end
The error reported by GDB is:
Argument to arithmetic operation not a number or boolean
I have set the language to c. set language c
The error message is reported between the first and second 'x ...' outputs.
When I type the commands at the GDB prompt I do not get an error and the operation works as expected.
I am debugging a legacy program. It does not have GDB compatible debug symbols.
I am using a GDB cross for M68k, v4.3.2
This:
set $lowaddr=(short*)($arg0)
creates a GDB convenience variable of type short*. GDB will refuse bitwise operations on anything that is not a number, as can be trivially seen from trying:
(gdb) set $foo = (short*)0x1234
(gdb) p $foo
$1 = (short *) 0x1234
(gdb) p $foo & 0xff
Argument to arithmetic operation not a number or boolean.
So perform your operations on integers, and cast to pointer only when necessary. In your snippet you only use the pointer to x/h, which doesn't need a pointer at all.
Related
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).
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.
I'm using GDB to debug code that was assembled with
nasm -felf64 -Fdwarf
when I want to examine the value at a label symbol, say
var_h: dq -1
using
print var_h
GDB assumes that the value is 32-bit and only gives me the lowest 4 bytes
x \1gx $var_h
gives an error along the lines of "cannot convert value to integer'
Very grateful for any ideas!
This should work:
(gdb) x/gx &var_h
Your other commands, as well as "along the lines of ..." make no sense.
Details matter, and you should always show actual commands you used and output you received, not vague approximations thereof.
I executed following commands in gdb and console output is as follows:
Rohan_gdb$ set $var = 15
Rohan_gdb$ p $var
$5 = 0xf
Rohan_gdb$ set $var = (int *)10
Rohan_gdb$ p $var
$6 = (int *) 0xa
Rohan_gdb$ set $char = "abc"
Rohan_gdb$ p $char
$7 = "abc"
Rohan_gdb$ set $char = (char *)"xyz"
evaluation of this expression requires the program to have a function "malloc".
(here I got error)
Rohan_gdb$ p $char
$8 = "abc"
Rohan_gdb$
Here I am debugging with target and not native debugging. I am using GNU gdb (GDB) 7.2 version. Is it possible to solve using scripts.
I don't know how to solve your specific problem, but I ran across something similar. Given the age of the question, maybe this'll provide a clue.
The problem is that your script is trying to store away a value in a buffer and it must allocated a new buffer for that storage. The storage requirement is likely the result of the cast or because that second string is not in the constant strings within your binary.
To fix, either change your code to not require a malloc (which is a bit of hit or miss, as far as I can tell). Or make the malloc symbol available; load a symbol table that allows gdb to resolve the "_malloc" symbol.
All values are interpreted in the current language. This means, for example, that if the current source language is C/C++ then searching for the string “hello” includes the trailing \0. The null terminator can be removed from searching by using casts, e.g.: {char[5]}"hello".
https://sourceware.org/gdb/onlinedocs/gdb/Searching-Memory.html
Example:
https://github.com/PhoenixInteractiveNL/emuDownloadCenter/wiki/Emulator-wincpc <-> WinCPC is the Borland Delphi port of an Amstrad CPC emulator called vbCPC.
F:\flynns_WinCPC>gdb wincpc.exe<br>
GNU gdb (GDB) 7.6<br>
...<br>
This GDB was configured as "i686-pc-mingw32".<br>
...<br>
Reading symbols from F:\flynns_WinCPC\wincpc.exe...(no debugging symbols found)...done.<br>
(gdb) info files<br>
Symbols from "F:\flynns_WinCPC\wincpc.exe".<br>
Local exec file:<br>
`F:\flynns_WinCPC\wincpc.exe', file type pei-i386.<br>
Entry point: 0x558448<br>
0x00401000 - 0x005587ec is CODE<br>
0x00559000 - 0x0055f7f8 is DATA<br>
0x007bf000 - 0x007c1b88 is .idata<br>
0x007c3000 - 0x007c301f is .rdata<br>
0x007c4000 - 0x007db530 is .reloc<br>
0x007dc000 - 0x00861c00 is .rsrc<br>
(gdb) find 0x00401000,0x00861c00,'m','e','m','o','r','y'<br>
0x48b224<br>
0x48b2e8<br>
0x48b312<br>
0x48b33a<br>
0x48b354<br>
0x48c2cc<br>
0x48cfcb<br>
0x82d910<br>
0x841484<br>
0x8456f9<br>
10 patterns found.<br>
(gdb) find 0x00401000,0x00861c00, <strong>{char[6]}</strong> "memory"<br>
evaluation of this expression requires the program to have a function "malloc".<br>
I've been doing some work on an unfamiliar codebase that uses UChar* as strings. Uchars are defined as follows (at least according to gdb)
(gdb) ptype UChar
type = short unsigned int
However, when I try to print these in gdb, I just get the address. I can also index into the pointer and retrieve the values of each character.
Is there any way to print a variable of type UChar* from within gdb and get back a meaningful string?
Also, this is on OS X, if that makes any difference.
Just define this command in your .gdbinit and type uc varname (uc will likely work as a short form for the ucharprint command you define)
define ucharprint
echo "
set $c = (unsigned short*)$arg0
while ( *$c )
if ( *$c > 0x7f )
printf "[%x]", *$c
else
printf "%c", *$c
end
set $c++
end
echo "\n
end
You don't need to worry about endianness since each unsigned short in your UTF-16 UChar type holds a code point (or half surrogate) as a native binary integer.
You first need to figure out what a UChar actually represents. It is likely UTF-16 or UCS-2 (but BE or LE?). Once you determine this, you want to provide (you can probably use existing code, such as iconv) a debug method to convert to UTF-8. See http://www.skynet.ie/~caolan/TechTexts/GdbUnicodePrinting.html for details.
print is the same as x;
x/1s 0x1234 -- will print out that location in memory as a string, if you keep hitting carrage return, it will print the next line... etc...
If you want to monitor something continually, use display/ with the same format specifier as x (print). "display/1s 0x1234" then every time you break via a breakpoint or a single step, you will see the information you configured print out .. updated etc...
if it is an ascii string, you might try to tell gdb to reinterpret:
(gdb) print (char*) theUcharPtr