gdb declares size of 0 for class field - c++

I loaded up a C++ library in gdb, started the built-in Python interpreter, and ran
import gdb
t = gdb.lookup_type('Some::Type')
field = t.fields()[0]
print(field.bitpos)
print(field.bitsize)
The output is
0
0
What does it mean for a field to have a size of 0?
I've run gdb.lookup_type on the class of the field and it's not empty. I think it's a virtual class because all it has is a vtable.

bitsize is only meaningful for bit fields or packed fields. For regular fields, the size is given by the type. Use
t.fields()[0].type.sizeof
to access the size.

Related

How to get source code from PyCodeObject in c python api?

Hi i'm using c python api.
I want to extract function object's source code.
I want pure python code (like def func: ... ) But if it is hard then, i want to
get py byte codes at least.
Here is my c++ code that i get PyCodeObject from PyFunctionObject.
//pObject is PyFunctionObject which is python standard lib's function.
PyFunctionObject* pFunctionObject = (PyFunctionObject*)pObject;
PyCodeObject* codeObject = (PyCodeObject*)pFunctionObject->func_code;
PyObject* strObject = codeObject->co_code; //get code from code object
char * sourceCode = PyString_AsString(strObject); //convert to string
But sourceCode variable(char*) always show only 1 byte.
How should i gonna get this?
There is a lot of ways to do this in python code side, like just use 'dis' or 'inspect' module.
But i want to do this by c python api.
P.S
I guess that the PyCodeObject's co_code member is an byte array.
I used visual studio debug memory view and saw co_code member's adjoined memory byte but it seems like a byte code array(just maybe).
Firstly, PyCodeObject->co_code is the generated byte code, not pure Python source code.
In Python, we could use inspect.getsource to get pure Python source code. And in C, you could also use it via PyObject_CallMethod

Dump all function symbols and their base address to text file in trace32

I am trying to import all the function symbols in the elf with the function base address to a text file.
I am using the below 2 commands to do that
PRinTer.FILE c:\temp\function_symbol.txt
WinPrint.symbol.list.function
But in this process, full function name is getting terminated. I am getting output like this:
__________address________|path\symbol_|type_____________________|scope_|location|info
P:C001608C--C00160E7|.sym_1\sym_2|(static void * ()) |module|static |frame: * . push
I want the address and full path\symbol(2nd column). Please note that the symbol table is very big and increasing clip board size and selecting "To Clipboard All" will not work. I know that if I have the function base address , I can get the function name. But, in my implementation, I need to know both base address and function full name for better efficiency.
I want to know if it is possible to increase width of 2nd column via some command so that I get full function names after using winprint command
The window sYmbol.List.Function has two columns (with white background) which have a flexible width. You can control the width of those flexible columns with the command WinTABS.
Thus, to export sYmbol.List.Function with a wide column for "path\symbol" use the following commands:
PRinTer.FILE c:\temp\function_symbol.txt ASCIIE
WinTABS 1000.
WinPrint.sYmbol.List.Function
By the way: The width of the address column on the left of the window (with gray background) is controlled via the 5th parameter of the WinPOS command.

HOW to get value stored in a python variable if only its address is given?

If a variable has address '20754060', how can we get the value stored in that address?
a=20754060 #consist of address of some variable
how can we get value stored in '20754060' location
You probably cannot, and even if you can - you really shouldn't. Screwing around with memory content, ignoring or standing in way of GC is WRONG and probably will cause some weird errors.
As people already mentioned: this is so wrong ;)
However, this is how you do it (just a start).
from ctypes import *
# create c_int (only ctype addresses work)
a = c_int(423)
# get address of a
address = addressof(a)
#print address (just for fun)
print address
# print content of address (this works for size 1)
print c_char_p(address)
#check that it is the same (423 is 1a7 in hex. Note MSB vs LSB)
print hex(423)
This prints out:
35746280
c_char_p('\xa7\x01')
0x1a7
The above works only in the case of ctype objects like c_int (=ctypes.c_int).
c_char_p function gets the values one byte at the time. For more complicated objects, things get really ugly really fast and probably there is a limit at some point. But if you want, start reading here:
http://docs.python.org/3/library/ctypes.html
try this, in my case it is working.
address = id(variable)
this gives the id of the variable, and use this id to check the value of the variable
ctypes.cast(address, ctypes.py_object).value

QtCreator debugger does not display values of std::string

I tried to debug my small little lexer and ran into this problem: the QtCreator-Debugger does not display any content of my std::string-variable. I tried to debug it in console and I got the same result, just plain structure information.
The version of QtCreator I used a few days ago did display the content of the strings. All other STL-Elements like std::vector, std::map, std::multimap, etc. display the correct data, it's just the std::string class which does not do the right.
After several hours of googling I found a lot of web pages which describe the creation of pretty printers, my really noobish approaches to fix this didn't help. Any ideas how I can get rid of this bug?
Note: The 'content' of the string-variables will always be displayed as 'not accessible'.
I use QtCreator 2.6 (QT5) for 64bit Linux OS.
Edit(1): I reinstalled everything from OS to Compilers and IDE... The strange is, when I build my project with optimization level 3 (-O3) QT can display std::strings.
The command line is the following:
clang++ -std=c++11 -O3 -g -c foo.cpp
When I remove -O3 std::strings are < not accessible >. Any ideas?
You can try to fix "/usr/share/qtcreator/debugger/stdtypes.py". As they use "hard-code assumption on member position" it seems like not working everywhere.
In my case - Linux x64, gcc 9.1 it works exactly like you described:
string not accessible
So find function def qdumpHelper_std__string(d, value, charType, format):
And change
(size, alloc, refcount) = d.split("ppp", data - 3 * d.ptrSize())
to
(size, alloc, refcount) = d.split("ppp", value.address() + d.ptrSize())
Also comment d.check(0 <= size and size <= alloc and alloc <= 100*1000*1000) or change it to something like
if size > 1000:
size = 1000
On my system std::string has next structure
pointer 8 byte
size 8 byte
union 16 byte
And this union field can change its meaning depends on string size. So we need to comment that size < alloc check.
value.address() - the address of the string object, so value.address() + d.ptrSize()will point to size, and value.address() + 2 * d.ptrSize() point to that union, which contain alloc size value, from time to time.
Just look at your std::string class declaration so you will get structure on your system.
And after the fix:
fixed debuger view
Works both - when "system GDB pretty printers" checked and clear
Try this, it worked for me.
In Qt Creator menu bar:
Tools -> Options -> Debugger
Uncheck the option (Load system GDB pretty printers)
To clarify and sum up AstoBasto post:
In file: /usr/share/qtcreator/debugger/stdtypes.py replace this function:
def qdumpHelper_std__string(d, value, charType, format):
[...]
With this:
def qdumpHelper_std__string(d, value, charType, format):
if d.isQnxTarget():
qdumpHelper__std__string__QNX(d, value, charType, format)
return
if d.isMsvcTarget():
qdumpHelper__std__string__MSVC(d, value, charType, format)
return
data = value.extractPointer()
# We can't lookup the std::string::_Rep type without crashing LLDB,
# so hard-code assumption on member position
# struct { size_type _M_length, size_type _M_capacity, int _M_refcount; }
(size, alloc, refcount) = d.split("ppp", value.address() + d.ptrSize())
refcount = refcount & 0xffffffff
d.check(refcount >= -1) # Can be -1 according to docs.
if size > 4002:
size = 4002
d.putCharArrayHelper(data, size, charType, format)
And this works (at least on Kubuntu 19.10).

gdb\bfd: get child variable address or size or offset

I'm using gdb and libbfd to retrieve global variables information from an elf file and show it.
I can get the following data from libbfd: Global Variable name, address and size.
I retrieve the type of the variables and its children using gdb and gdb\MI (ptype, whatis, -var-create & -var-list-children).
How can I get the address\size\offset from parent of all the children?
e.g
type = struct {\n"
unsigned char count;\n"
unsigned char time;\n
}\n
If a variable A of this type is in address 0x000100, I want to show that A.count is in 0x000100 with size 0x1 and A.time is in 0x000101 with size 0x1.
EDIT:
I've read that gdb can read the DWARF info, but I can't figure out how can I get this information from gdb.
Here's what I did eventually.
To get the size, I used:
p sizeof(A.time)
and to get the address I used:
p /a &A.time
NOTE: This only applies for variable of a size bigger then 1 byte.
To be able to get bitfields size and offset in bits, I had to recompile GDB according to the suggestion offered in nabble: Address of bitfield element bug?