print - Accessing program information that gdb sees in C++





memory string (5)


Library to read ELF file DWARF debug information

There's a new kid on the block - pyelftools - a pure Python library for parsing the ELF and DWARF formats. Give it a try.

It aims to be feature-complete and is currently in active development, so any problems should be handled quickly and enthusiastically :-)

I have a program written in C++, on Linux, compiled with -g.

When I run it under gdb, I can

1) set breakpoints
2) at those breakpoints, print out variables
3) see the stackframe
4) given a variable that's a structure, print out parts of the structure (i.e. how ddd displays information).

Now, given that my program is compiled with "-g" -- is there anyway that I can access this power within my program itself?

I.e. given that my program is compiled with "-g", is there some

std::vector<string> getStackFrame();

function I can call to get the current stackframe at the current point of execution?

Given a pointer to an object and it's type ... can I do

std::vector getClassMember(class_name);

?

I realize the default answer is "no, C++ doesn't support that level of introspection" -- however, recall I'm on linux, my program is compiled with "-g", and gdb can do it, so clearly the inforamtion is there. Question is: is there some API for accessing it?

EDIT: PS Naysers, I'd love to see a reason for closing this question.







I remember using libbfd to get function names from object files. It's a library for reading object formats, maybe you can also read other debug information using this. (I don't know to be honest)

http://www.skyfree.org/linux/references/bfd.pdf




You might be interested in the DWARF library from pydevtools:

>>> from devtools.dwarf import DWARF
>>> dwarf = DWARF('test/test')
>>> dwarf.get_loc_by_addr(0x8048475)
('/home/emilmont/Workspace/dbg/test/main.c', 36, 0)
>>> print dwarf
.debug_info
COMPILE_UNIT<header overall offset = 0>
<0><11> compile_unit
producer: GNU C 4.4.3
language: C89
name: a/test.c
comp_dir: /home/emilmont/Workspace/dbg/test
low_pc: 0x080483e4
high_pc: 0x08048410
stmt_list: 0
[...]



This is not an answer, but it's hard to read if I put results in comment.

I get these results with a Mac Pro (Westmere 6-Cores Xeon 3.33 GHz). I compiled it with clang -O3 -msse4 -lstdc++ a.cpp -o a (-O2 get same result).

clang with uint64_t size=atol(argv[1])<<20;

unsigned    41950110000 0.811198 sec    12.9263 GB/s
uint64_t    41950110000 0.622884 sec    16.8342 GB/s

clang with uint64_t size=1<<20;

unsigned    41950110000 0.623406 sec    16.8201 GB/s
uint64_t    41950110000 0.623685 sec    16.8126 GB/s

I also tried to:

  1. Reverse the test order, the result is the same so it rules out the cache factor.
  2. Have the for statement in reverse: for (uint64_t i=size/8;i>0;i-=4). This gives the same result and proves the compile is smart enough to not divide size by 8 every iteration (as expected).

Here is my wild guess:

The speed factor comes in three parts:

  • code cache: uint64_t version has larger code size, but this does not have an effect on my Xeon CPU. This makes the 64-bit version slower.

  • Instructions used. Note not only the loop count, but the buffer is accessed with a 32-bit and 64-bit index on the two versions. Accessing a pointer with a 64-bit offset requests a dedicated 64-bit register and addressing, while you can use immediate for a 32-bit offset. This may make the 32-bit version faster.

  • Instructions are only emitted on the 64-bit compile (that is, prefetch). This makes 64-bit faster.

The three factors together match with the observed seemingly conflicting results.