//gdb-call-lambda.cpp
#include <iostream>
void do_something(void) {
std::cout << "blah blah" << std::endl;
auto lambda_func = [](void){
std::cout << "in lambda" << std::endl;
return;
};
lambda_func();
std::cout << "..." << std::endl;
return;
}
int main(int argc, char **argv) {
do_something();
return 0;
}
In this example program, if you compile (g++ gdb-call-lambda.cpp --std=c++11 -g
) and then run it in gdb (gdb ./a.out
), you can have GDB call any "normal" function. Example:
(gdb) break main
Breakpoint 1 at 0x4008e7: file gdb-call-lambda.cpp, line 20.
(gdb) r
Starting program: /home/keithb/dev/mytest/gdb-call-lambda/a.out
Breakpoint 1, main (argc=1, argv=0x7fffffffdfb8) at gdb-call-lambda.cpp:20
20 do_something();
(gdb) call do_something()
blah blah
in lambda
...
However, if you then try to call the lambda:
(gdb) break do_something
Breakpoint 2 at 0x400891: file gdb-call-lambda.cpp, line 5.
(gdb) c
Continuing.
Breakpoint 2, do_something () at gdb-call-lambda.cpp:5
5 std::cout << "blah blah" << std::endl;
(gdb) n
blah blah
12 lambda_func();
(gdb) n
in lambda
14 std::cout << "..." << std::endl;
(gdb) call lambda_func()
Invalid data type for function to be called
GDB kinda freaks out. So my question is thus: how do you call a lambda in GDB? Asking GDB what it expects reveals nothing of interest when compared to a normal function:
(gdb) whatis lambda_func
type = __lambda0
(gdb) whatis do_something
type = void (void)
I went to see if lambda_func has any special members, eg a function pointer to call, akin to std::function and/or std::bind:
(gdb) print lambda_func
$1 = {<No data fields>}
No special members? Okay maybe it's just a glorified function pointer?
(gdb) call ((void (void)) lambda_func)()
Program received signal SIGSEGV, Segmentation fault.
0x00007fffffffdeaf in ?? ()
The program being debugged was signaled while in a function called from GDB.
GDB remains in the frame where the signal was received.
To change this behavior use "set unwindonsignal on".
Evaluation of the expression containing the function
(at 0x0x7fffffffdeaf) will be abandoned.
When the function is done executing, GDB will silently stop.
So I'm not even 100% sure what order to pass any arguments or especially captured types.
I tried additionally call lambda_func.operator()()
, call lambda_func::operator()
, call lambda_func::operator()()
, call __lambda0
, call __lambda0()
, call __lambda0::operator()
, call __lambda0::operator()()
, all to no avail.
A search on google reveals things about setting breakpoints in lambdas, but nothing on how to call those lambdas from the debugger.
For what it's worth, this is on Ubuntu 14.04 64-bit using g++ 4.8.2-19ubuntu1 and gdb 7.7-0ubuntu3.1
I was expecting call __lambdaX::operator()()
works but it doesn't. I think it is related to GCC implementation. I am not sure if there is a better way but this is my workaround solution when I need to call lambda in GDB.
Briefly, GDB has disassemble
command and it gives __lambda0::operator()() const
as debug information at the call
instruction line. Then, convert that address into a function pointer and call it.
Example explains better.
$ g++ -g -std=c++0x lambda.cpp
$ ./a.out
blah blah
in lambda
...
GDB:
$ gdb ./a.out
GNU gdb (GDB) Fedora 7.7.1-13.fc20
Copyright (C) 2014 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 "x86_64-redhat-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./a.out...done.
(gdb) b do_something()
Breakpoint 1 at 0x4008a3: file lambda.cpp, line 4.
(gdb) run
Starting program: /home/alper/cplusplus/a.out
Breakpoint 1, do_something () at lambda.cpp:4
4 std::cout << "blah blah" << std::endl;
Missing separate debuginfos, use:
(gdb) n
blah blah
11 lambda_func();
Disassemble do_something
(gdb) disassemble do_something
Dump of assembler code for function do_something():
0x40089b <+0>: push %rbp
0x40089c <+1>: mov %rsp,%rbp
0x40089f <+4>: sub $0x10,%rsp
=> 0x4008a3 <+8>: mov $0x4009fb,%esi
0x4008a8 <+13>: mov $0x601060,%edi
0x4008ad <+18>: callq 0x400750 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt>
0x4008b2 <+23>: mov $0x400770,%esi
0x4008b7 <+28>: mov %rax,%rdi
0x4008ba <+31>: callq 0x400760 <_ZNSolsEPFRSoS_E@plt>
0x4008bf <+36>: lea -0x1(%rbp),%rax
0x4008c3 <+40>: mov %rax,%rdi
0x4008c6 <+43>: callq 0x400870 <__lambda0::operator()() const>
0x4008cb <+48>: mov $0x400a05,%esi
0x4008d0 <+53>: mov $0x601060,%edi
0x4008d5 <+58>: callq 0x400750 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt>
0x4008da <+63>: mov $0x400770,%esi
0x4008df <+68>: mov %rax,%rdi
0x4008e2 <+71>: callq 0x400760 <_ZNSolsEPFRSoS_E@plt>
0x4008e7 <+76>: nop
0x4008e8 <+77>: leaveq
0x4008e9 <+78>: retq
GDB outputs line callq 0x400870 <__lambda0::operator()() const>
so convert 0x400870
into a function pointer and call it.
(gdb) call ((void (*)()) 0x400870)()
in lambda
(gdb) call ((void (*)()) 0x400870)()
in lambda
(gdb) call ((void (*)()) 0x400870)()
in lambda
Note: If GCC inlines the lambda, there is nothing to call. For example, if the example above is compiled with optimisation switch -O3
, there is no line with __lambda0::operator()() const
in GDB disassemble
output.
In a less synthetic use case I had success in calling the lambda by calling it as
call myLambda.operator()(param1,param2)
But in the test case in the OP GDB appears to think the function is inlined — even though it's not. I've reported this as bug 28137.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With