Michael Mol
Michael Mol

Reputation: 538

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

I discovered that I get two different results when examining a variable, depending on whether I implicitly or explicitly use the type GDB understands that variable to be:

Navigate to my stack frame

(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 */

Print the what p_ctx points to, as GDB understands it, implicitly using whatever GDB knows about its type.

(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}

Ask GDB for the name of the type

(gdb) whatis p_ctx
type = plugin_ctx *

Specify that type name explicitly when printing p_ctx, and we get a very different output.

(gdb) print * ( (plugin_ctx *) p_ctx )
$27 = {offset = 0, pfd = 0x0, plugin_options = 0x0, fname = 0x0, reader = 0x0, writer = 0x0, 
  where = '\000' <repeats 16 times>, "\020\273\002\070j\177", '\000' <repeats 26 times>, "\225\031\327Mj\177\000\000\240\000\000\000\000\000\000\000%\001\000\000\000\000\000\000@e\317Mj\177\000\000\370&\322Mj\177\000\000\375\377\377\377\377\377\377\377\260\234\337Mj\177\000\000\001\000\000\000\000\000\000\000@\ntBj\177\000\000\060\000\000\000\000\000\000\000*\000\000\000\000\000\000\000\177\000\000\000\000\000\000\000@\322\000\070j\177\000\000P\aCBj\177\000\000Ȋ\260\270i\225\fbЉ\342Mj\177\000\000\000\035c\001\000\000\000\000َ\372<\375\364\343\372\300\237\342Mj\177\000\000\000\337\325"..., replace = 0}

Ask GDB to tell us about types named 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;

Well there's our problem; we're in python-fd.c, and when we explicitly specify a type name, we get bpipe-fd's type instead!

As evidence:

(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;
} *

compared to:

(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;
}

So, when presented with multiple types named plugin_ctx, how to I tell gdb which one to use? I've tried:

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

which obviously did not work. I have not found anything in GDB's manual on how to address this kind of disambiguation when it applies to types. So what's the preferred approach in this situation?

Upvotes: 2

Views: 1285

Answers (1)

Michael Mol
Michael Mol

Reputation: 538

I'll flesh out this answer with examples as I get it working, but based on @n.m's feedback discussion on the core post and the information found within another thread, here's a workaround:

Create an object file with the type you want, with an unambiguous name.

#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;
} ;
  1. Using gcc's add-symbol-file command, pull that object file into the running process.
  2. You should now be able to use the new type.

Upvotes: 1

Related Questions