31

I know that gdb allows for an already declared variable to be set using the set command.

Is it possible for gdb to dynamically declare a new variable inside the scope of a given function?

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
Randomblue
  • 112,777
  • 145
  • 353
  • 547
  • 11
    What good would it do? The code wouldn't be aware of its existence. – James M Apr 23 '12 at 16:06
  • Agree with @JamesMcLaughlin anyway to be clear: **no**, it's only for inspection. – Adriano Repetti Apr 23 '12 at 16:09
  • 6
    Are you sure you don't want a gdb variable? You *can* create variables in the context of gdb for your convenience, like `set $foo = ...` and later reference `$foo`. Obviously such variables are in no way visible to the running code, however. – FatalError Apr 23 '12 at 16:14
  • it's not only for inspection. you can change variable values in gdb: http://stackoverflow.com/questions/3305164/how-to-modify-memory-contents-using-gdb. http://www.delorie.com/gnu/docs/gdb/gdb_118.html. you can't declare new variables though, as far as i know. – thang Feb 10 '14 at 07:55
  • Does this answer your question? [GDB: Create local variable?](https://stackoverflow.com/questions/8275135/gdb-create-local-variable) – xhienne Jan 15 '21 at 12:13

3 Answers3

35

You can dynamically allocate some space and use it to store a new variable. Depending on what you mean by "scope of the current function" it may not be what you want.

But here is how it looks like, when you have function func() that takes a pointer to an output parameter:

set $foo = malloc(sizeof(struct funcOutStruct))
call func($foo)
p *$foo
call (void) free($foo)
Illia Bobyr
  • 730
  • 6
  • 16
  • In my case, calling `func($foo)` from gdb did not work (`Undefined command: "func".`), but calling `set $garbage = func($foo)` worked. In addition, I had to use `malloc` instead of `alloc`. – nullromo Dec 02 '18 at 22:40
  • 1
    @nullromo Thanks - corrected the example, added `call` - it executes an expression and discards the result. And fixed `malloc`. – Illia Bobyr Dec 19 '18 at 05:55
  • It seems now you have to cast to void when a function such as `free` is use like in ``` (gdb) call free(0) 'free' has unknown return type; cast the call to its declared return type (gdb) call (void) free(0) ``` – aitzkora Aug 02 '22 at 13:41
  • @aitzkora Thank you, updated answer. What about the `call func($foo)` part? It would be strange for gdb to require an explicit type to be specified there. But, at the same time, it is unclear to me, why it would need it for the `free` call. – Illia Bobyr Aug 03 '22 at 00:31
  • You right, I have also to add a cast (void) to call func($foo) if that function has no return type. I do not know if it is due to my gdb implementation, but it is also needed – aitzkora Aug 03 '22 at 09:28
  • It seems like you are just missing debug information for the functions you are trying to call. It is explained in the GDB docs: https://sourceware.org/gdb/onlinedocs/gdb/Calling.html#Calling-functions-with-no-debug-info I do not think it should be included in the answer, as, I would imagine, in most cases people would have debug information for the code they are debugging. And if they do not - it is a separate question. – Illia Bobyr Aug 03 '22 at 20:53
19

For C (and probably C++) code, that would be very hard, since doing so in most implementations would involve shifting the stack pointer, which would make the function's exit code fail due to it no longer matching the size of the stack frame. Also all the code in the function that accesses local variables would suddenly risk hitting the wrong location, which is also bad.

So, I don't think so, no.

unwind
  • 391,730
  • 64
  • 469
  • 606
  • Strictly speaking this is correct, it would be a pain to get the variables on the stack. But if you're ok with static variables, Ilya's solution works. – r_2 Dec 16 '18 at 23:46
7

that's how I used to print variables

(gdb) set $path=((ngx_path_t     **)ngx_cycle->paths.elts)[2]
(gdb) print *$path
    $16 = {
        name = {
            len = 29,
            data = 0x80ed15c "/usr/local/nginx/fastcgi_temp"
            },
        len = 5,
        level = {1, 2, 0},
        manager = 0,
        loader = 0,
        data = 0x0,
        conf_file = 0x0,
        line = 0
    }
laalto
  • 150,114
  • 66
  • 286
  • 303
jasonxiaole
  • 71
  • 1
  • 1