cydonian
cydonian

Reputation: 1816

Concatenate GDB convenience variables

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

Upvotes: 4

Views: 3180

Answers (2)

Craig Ringer
Craig Ringer

Reputation: 324445

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.

Upvotes: 2

Tom Tromey
Tom Tromey

Reputation: 22519

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.

Upvotes: 5

Related Questions