Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Concatenate GDB convenience variables

Tags:

gdb

I'd like to do something like this, but can't figure out the right GDB commands.

Let's say I start debugging a process, and there is a file I'd like to pass as a parameter to that process. I want to construct the name of the file at runtime with a gdb command script that would look something like this:

set $var1 = "path"
set $var2 = "to"
set $var3 = "file"
set $var4 = $var1+"/"+$var2+"/"+$var3
file /process/to/debug
run params $var4
like image 307
cydonian Avatar asked Oct 24 '25 02:10

cydonian


2 Answers

There's no really good built-in way to do this :-(

You might think, as I did, that the eval command could be used. However, for the specific case of string substitutions, eval requires the inferior (FWIW this seems like a gdb bug to me).

That is, this works:

(gdb) set $v1 = 7
(gdb) eval "set $v2 = \"%d\"", $v1
(gdb) p $v2
$1 = "7"

But this does not:

(gdb) set $v3 = "hi"
(gdb) eval "set $v4 = \"%s\"", $v3
evaluation of this expression requires the target program to be active

There are still two routes you can use.

The traditional one is to use set logging in combination with output (printf won't work - it fails just as the above does) and perhaps shell sed or the like, to turn the strings into some gdb commands in a file. Then source that file.

Another way is to write some Python code to do this. You could either write a convenience function that concatenates strings, or you could write a new command that does whatever you happen to want.

like image 71
Tom Tromey Avatar answered Oct 25 '25 19:10

Tom Tromey


This gdb Python user-defined convenience function implements a $concat function you use on arbitrary rvalues for this purpose.

class Concat(gdb.Function):
    """$concat(arg, [arg, [arg, [...]]]): Concatenate strings"""

    def __init__(self):
        super(Concat, self).__init__("concat")

    def _unwrap_string(self, v):
        try:
            return v.string()
        except gdb.error:
            return str(v)
    
    def invoke(self, *args):
        return ''.join([ self._unwrap_string(x) for x in args])

Concat()
(gdb) source concat.py
(gdb) help function concat
$concat(arg, [arg, [arg, [...]]]): Concatenate strings
(gdb) p $concat(1,2,"foo",3,"bar")
$10 = "12foo3bar"
(gdb) p $concat( (char*)0 )
$14 = "0x0"
(gdb) $concat(argv[0])
$20 = "test_program"
(gdb) detach
...
(gdb) p $concat("works", " ", "when", " ", "detached")
$23 = "works when detached"

This implementation might do odd things if you aren't specific about input types and works best on actual strings.

like image 22
Craig Ringer Avatar answered Oct 25 '25 19:10

Craig Ringer



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!