How to print a c++ object members using GDB from an address if the object's class type is like A::B

61,552

Solution 1

Works for me:

g++ -g test.cpp -o test
gdb test
(gdb) break main
(gdb) r


Breakpoint 1, main () at test.cpp:22
22      A::B *p = new A::B(100);
(gdb) n
24      p->print();
(gdb) n
m_a is 100
26      int *q = 0;
(gdb) p p
$1 = (A::B *) 0x602010
(gdb) p (A::B *) 0x602010
$2 = (A::B *) 0x602010
(gdb) p *((A::B *) 0x602010)
$3 = {m_a = 100}

It works for me. What are you using (gcc version, OS, compilation flags?)

Solution 2

I know that this is labeled as answered, but I was able to reproduce this problem using gdb on OS X (GNU gdb 6.3.50-20050815 (Apple version gdb-1820) (Sat Jun 16 02:40:11 UTC 2012)) and the works-for-me solution didn't answer it for me.

Turns out there was another question on SO that did have an answer which worked, so I think it's worth pulling into this quesiton:

Why gdb casting is not working?

The short answer is that you may have to single-quote your namespaced variables:

(gdb) p ('MyScope::MyClass'*) ptr;

Share:
61,552
Gary Hu
Author by

Gary Hu

Updated on July 09, 2022

Comments

  • Gary Hu
    Gary Hu almost 2 years

    From this link gdb interpret memory address as an object we know that, if an object of class type A is at a specific address such as 0x6cf010, then we can use:

    (gdb) p *(A *) 0x6cf010 
    

    to print the member elements of this object.

    However, this seems doesn't work when c++ namespace is involved. That is, if the object of class type A::B, then all the following trying doesn't work:

    (gdb) p *(A::B *) 0x6cf010
    (gdb) p *((A::B *) 0x6cf010)
    

    So, who knows how to print the object elements under this conditions?


    We can use the following deliberate core code to try to print the members of p from the address (we can use "info locals" to show the address).

    #include <stdio.h>
    
    namespace A
    {
        class B
        {
        public:
            B(int a) : m_a(a) {}
    
            void print()
            {
                printf("m_a is %d\n", m_a);
            }
    
        private:
            int  m_a;
        };
    }
    
    int main()
    {
        A::B *p = new A::B(100);
    
        p->print();
    
        int *q = 0;
    
        // Generating a core here
        *q = 0;
        return 0;
    

    }

  • Gary Hu
    Gary Hu over 12 years
    It's wired! why I found that: (gdb) p p $1 = (A::B *) 0x1878f010 (gdb) p (A::B *) 0x1878f010 A syntax error in expression, near ) 0x1878f010'. (gdb) p *((A::B *) 0x1878f010) A syntax error in expression, near ) 0x1878f010)'.
  • sehe
    sehe over 12 years
    it's wired? I hope that is a good thing. The rest of the comment didnot make sense to me, unfortunately
  • Gary Hu
    Gary Hu over 12 years
    I use the same compilation flags with you. My os is CentOS 5 x64. GDB version is: GNU gdb Fedora (6.8-27.el5) Copyright (C) 2008 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <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"...
  • sop
    sop over 7 years
    you could use another variable than p...
  • sehe
    sehe over 7 years
    @sop Yes. Why do you mention it?
  • sop
    sop over 7 years
    it's a little confusing :P