如何使用GDB从C ++函数逐步调试std :: function用户代码? [英] How to step debug into std::function user code from C++ functional with GDB?

查看:160
本文介绍了如何使用GDB从C ++函数逐步调试std :: function用户代码?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

例如,使用:

#include <functional>
#include <iostream>

int myfunc(int i){ return i + 1; }

int main() {
    std::function<int(int)> f = myfunc;
    int i = f(1);
    std::cout << i << std::endl;
}

编译为:

g++ -ggdb3 -O0 -std=c++11 -Wall -Wextra -pedantic -o main.out main.cpp

如果我尝试对调用f(1)进行step,那么它将首先使我进入C ++标准库代码,而我要么必须认真思考,然后做正确的next/step顺序,或者在达到实际myfunc通话之前先哑巴并按step 17次.

if I try to do a step into the call f(1), then it first leads me in to C++ standard library code, and I either have to think really hard and do the right next/step sequence, or be dumb and hit step 17 times before reaching the actual myfunc call.

是否有更简单的方法可以解决此问题,也许使用一些现有的GDB/Python脚本?

Is there an easier way to go about this, maybe with some existing GDB/Python script?

这基本上是由Microsoft人员为Visual Studio完成的,如以下所述:

This was basically done by Microsoft people for Visual Studio as mentioned at: https://devblogs.microsoft.com/cppblog/improving-the-debugging-experience-for-stdfunction/

我喜欢在Ubuntu中默认情况下可以进入stdlibc ++并具有

I like it that is is possible to step into the stdlibc++ by default in Ubuntu and have already used it before, but it would be awesome if GDB could step into std::function user code by default, and have some other mechanism to go into libstdc++ for this specific case.

我很想变脸,只使用下面的Python GDB脚本重复n次命令:

I'm tempted to go a bit cheeky and just use the following Python GDB script that repeats a command n times: gdb - perform a command n times which allows me to do:

repeat-cmd 17 s

相关: QtCreator调试器:进入std :: function

在Ubuntu 18.04,GDB 8.1,GCC 7.4中进行了测试.

Tested in Ubuntu 18.04, GDB 8.1, GCC 7.4.

推荐答案

在您的用例中不起作用的第一件事是

The first thing which will not work in your use case is

gdb skip -gfile bits/*.h

gdb skip -gfile bits/*.h

正如您已经提到的,这还将跳过从std库中调用的代码.

As you already mentioned, this will skip also over your code which was called from within the std library.

下一个想法:跳过带有已知名称"的功能.正如我们通常在函数名称前面使用std::一样,使用了以下.gdbinit.看起来好多了:

Next idea: Skipping over functions with "known name". As we have typically std:: in front of the function name a used the following .gdbinit. It looks much better:

sys.path.insert(0, '/usr/share/gcc-9/python/')
from libstdcxx.v6.printers import register_libstdcxx_printers
register_libstdcxx_printers (None)

import gdb
import re

def stop_handler(event):
    frame_name = gdb.selected_frame().name();
    if re.search("(operator new.*)|(^__gnu_cxx::.*)|(^std::.*)", frame_name) != None:
        gdb.execute("step")

gdb.events.stop.connect(stop_handler)
end

我现在搜索了一段时间,找到了一些将当前文件/行号组合放入python的东西,但是没有找到任何东西.是否可以通过python访问当前文件名和行号?如果是这样,在这种情况下这将更加简单.如果有人可以在此处添加一些信息,那就太好了!

I searched now a while to find something to get the current file/line-number combination into python but did not find anything. Is there any python access to the current file name and line number? If so, this will be much simpler in this case. Would be nice if someone can add some info's here!

备注:在ddd中,它的效果不是很好,因为gui无法识别python的内部步骤.因此,绿色箭头停留在最后的阶梯线上,而不是当前的.如果有人也知道这种情况下的把戏,欢迎您的帮助!

Remark: in ddd that will work not very well, as an internal step from python will not be recognized by the gui. So the green arrow stays on the last stepped line and not the current one. If someone knows also a trick in such a case, any help is welcome!

更新:

如果您将以下内容用作.gdbinit

If you use the following as .gdbinit

python
import sys
sys.path.insert(0, '/usr/share/gcc-9/python/')
from libstdcxx.v6.printers import register_libstdcxx_printers
register_libstdcxx_printers (None)

import gdb
import re

def stop_handler(event):
    sal = gdb.selected_frame().find_sal()
    if sal == None:
        gdb.execute("step")
    else:
        symtab = sal.symtab;
        if symtab == None:
            gdb.execute("step")
        else:
            file_name = symtab.fullname();
            if re.search("(.*bits.*)", file_name ) != None:
                gdb.execute("step")

gdb.events.stop.connect(stop_handler)
end

一切都可以在我的PC上完美运行.作为附加提示:如果使用ddd,则可以打开backtrace窗口,然后绿色箭头也将遵循python内部gdb步骤.那对我来说很完美!谢谢你的问题! :-)

Everything works perfectly on my pc. As an additional hint: If using ddd, you can open the backtrace window and then the green arrow will follow also the python internal gdb steps. That works perfectly for me! Thanks for the question! :-)

也许可以对正则表达式进行更新以适合过滤更多的外部库,或者更具选择性.

Maybe the regexp can be updated to fit for filtering more external libs or to be more selective.

这篇关于如何使用GDB从C ++函数逐步调试std :: function用户代码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆