0

In linux, with gdb debugger I can print every object if the program is compiled with -g option. Is it possible to write a function like

template<typename T> ostream& to_stream(ostream& out, const T& obj);

that serialize my object with the name and type?

Naturally with help of gdb call or system call or other.

2
  • 2
    We need more details. What are you trying to accomplish? Commented Feb 21, 2020 at 16:46
  • Are you looking for some debugging information API for C++? Commented Mar 11, 2022 at 10:24

2 Answers 2

0

If you don't have gdb, you can't do much.

magic_get works in some limited cases.

For the rest you mostly have to manually specify the field names, possibly through a macro to make it more convenient, but still manual.

visual c++ - Printing values of all fields in a C++ structure - Stack Overflow


If you have gdb (as in, you can guarantee the program will be run in gdb) however, (as specified in the question), use a technique in c - Sending commands to gdb from the debugged program - Stack Overflow we have (you need the Python code copied from that post run in gdb)

void gdb_run([[maybe_unused]] char const* str) {}

template<class T> void gdb_pretty_print([[maybe_unused]] T const& arg){
    gdb_run("up\nprint arg");
}

struct Example{
    int a;
    char b;
};

int main(){
    gdb_pretty_print(Example{1, '0'});
}

If you want to get the result to pass to C++ you can do something like

template<class T> void gdb_pretty_print([[maybe_unused]] T const& arg){
    char const* volatile result=nullptr;
    gdb_run("up\n"
            "python gdb.set_convenience_variable('result', gdb.execute('print arg', to_string=True))\n"
            "set result=$result");
    __builtin_printf("result = %s\n", result);
}

Actually I'm not sure if volatile will do it, alternatively compile the particular with -O0.


Alternatively you may try to set break point within gdb_pretty_print itself, but I tried it's pretty hard.

class GdbPrettyPrint(gdb.Breakpoint):
    def __init__(self, function_name):
        super().__init__(function_name, internal=1)
        self.silent = True

    def stop(self):
        gdb.execute("print arg")
        return False

def set_breaks():
    for b in gdb.rbreak("^gdb_pretty_print<"):
        GdbPrettyPrint(b.location.split(":")[-1])
        b.delete()

You have to run the set_breaks() function unfortunately. For some reason rbreak alone doesn't work for me.

Example program

template<class T> void gdb_pretty_print(T const& arg){
    (void) arg;
}

struct Example{
    int a;
    char b;
};

int main(){
    gdb_pretty_print(Example{1, '0'});
}
Sign up to request clarification or add additional context in comments.

Comments

-1

Yes, you can do it with python Pretty Printing API. To start with pretty printing, you can look at this question and Tom Tromey's blog: http://tromey.com/blog/?p=524.

1 Comment

(I didn't downvote but) I think you misunderstood the question. it asks for how to write C++ function (even before the recent edit)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.