当存在多个相同名称的类型时,在gdb中通过名称指定正确的类型

Specifying correct type by name in gdb when multiple types of same name exist

本文关键字:类型 gdb 存在      更新时间:2023-10-16

我发现在检查一个变量时得到两个不同的结果,这取决于我是隐式地还是显式地使用GDB理解该变量的类型:

导航到我的堆栈框架

(gdb) frame 2 #2 0x00007f6a4277e87d in PyCheckFile (fname=0x7f6a338704b8 "/usr/lib/debug/sbin", ctx=0x7f6a3803ddf8) at python-fd.c:2054 2054 pFunc = PyDict_GetItemString(p_ctx->pDict, "check_file"); /* Borrowed reference */

输出p_ctx指向什么,GDB理解它,隐式地使用GDB所知道的关于它的类型。

(gdb) print *p_ctx
$26 = {backup_level = 0, python_loaded = false, plugin_options = 0x0, module_path = 0x0, module_name = 0x0, 
  fname = 0x0, link = 0x0, object_name = 0x0, object = 0x0, interpreter = 0x7f6a3802bb10, pModule = 0x0, 
  pDict = 0x0, bpContext = 0x0}

向GDB询问类型

的名称
(gdb) whatis p_ctx
type = plugin_ctx *

在打印p_ctx时显式指定类型名称,我们得到一个非常不同的输出。

(gdb) print * ( (plugin_ctx *) p_ctx )
$27 = {offset = 0, pfd = 0x0, plugin_options = 0x0, fname = 0x0, reader = 0x0, writer = 0x0, 
  where = '00' <repeats 16 times>, "202730270j177", '00' <repeats 26 times>, "22531327Mj177000024000000000000000%01000000000000@e317Mj1770000370&322Mj1770000375377377377377377377377260234337Mj17700000100000000000000@ntBj17700006000000000000000*0000000000000017700000000000000@3220070j1770000PaCBj1770000Ȋ260270i225fbЉ342Mj17700000035c0100000000َ372<375364343372300237342Mj177000000337325"..., replace = 0}

让GDB告诉我们关于plugin_ctx的类型:

(gdb) info types ^plugin_ctx$
All types matching regular expression "^plugin_ctx$":
File bpipe-fd.c:
plugin_ctx;
File python-fd.c:
plugin_ctx;

这就是我们的问题;我们在python-fd中,当我们显式指定类型名称时,我们得到的是bpipe-fd的类型!

作为证据:

(gdb) ptype p_ctx
type = struct plugin_ctx {
    int32_t backup_level;
    bool python_loaded;
    char *plugin_options;
    char *module_path;
    char *module_name;
    char *fname;
    char *link;
    char *object_name;
    char *object;
    PyThreadState *interpreter;
    PyObject *pModule;
    PyObject *pDict;
    PyObject *bpContext;
} *
:相比

(gdb) ptype plugin_ctx
type = struct plugin_ctx {
    boffset_t offset;
    BPIPE *pfd;
    char *plugin_options;
    char *fname;
    char *reader;
    char *writer;
    char where[512];
    int replace;
}

那么,当出现多个名为plugin_ctx的类型时,我如何告诉gdb使用哪一个?我试过:

(gdb) print * ( ('python-fd.c'::plugin_ctx *) p_ctx )
A syntax error in expression, near `*) p_ctx )'.

显然不起作用。我没有在GDB的手册中找到任何关于如何在应用于类型时解决这种消歧的内容。那么在这种情况下,首选的方法是什么?

我将用示例充实这个答案,因为我让它工作,但基于@n。M对核心帖子的反馈讨论和在另一个线程中发现的信息,这是一个解决方案:

用您想要的类型创建一个object文件,并使用一个明确的名称。

#include <Python.h>
struct plugin_ctx2 {
    int32_t backup_level;
    bool python_loaded;
    char *plugin_options;
    char *module_path;
    char *module_name;
    char *fname;
    char *link;
    char *object_name;
    char *object;
    PyThreadState *interpreter;
    PyObject *pModule;
    PyObject *pDict;
    PyObject *bpContext;
} ;
  • 使用gccadd-symbol-file命令,将目标文件拉入正在运行的进程。
  • 你现在应该可以使用新类型了。