Pointer instantly 0x0 - c++

i have this code. the pointer turns 0x0 immediately before using it. short before, it had the correct address.
TreeViewColumn *col;
col = preview->get_column(pcFolder); /* col = 0x7fff5fc404a0 */
col->set_resizable(true); /* col = 0x0 */
i use Gtkmm 2.4, but it returns the expected value, it just turns 0x0. whats wrong?
gdb proof:
151 col = preview->get_column(pcFolder); /* col = 0x7fff5fc404a0 */
(gdb) print col
$1 = ('Gtk::TreeViewColumn' *) 0x7fff5fc404a0
(gdb) print *col
warning: can't find linker symbol for virtual table for `Gtk::TreeViewColumn' value
$2 = {
<Gtk::Object> = {
<Glib::Object> = {
<Glib::ObjectBase> = <invalid address>,
members of Glib::Object:
_vptr$Object = 0x7fff5fc06a20,
static object_class_ = {<No data fields>}
},
members of Gtk::Object:
static object_class_ = {<No data fields>},
referenced_ = 21,
gobject_disposed_ = 60
},
members of Gtk::TreeViewColumn:
static treeviewcolumn_class_ = {<No data fields>}
}
(gdb) next
152 col->set_resizable(true); /* col = 0x0 */
(gdb) print col
$3 = ('Gtk::TreeViewColumn' *) 0x0
(gdb) print *col
Cannot access memory at address 0x0
(gdb) next
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000000000000000
0x00000001000edc68 in Gtk::TreeViewColumn::set_resizable ()
i have no idea what causes this phenomenon. do you have?
Solution:
reading the documentation. the function returning pcFolder counts from 1, get_column() from 0.

The function call:
preview->get_column(pcFolder);
returns NULL.
When gdb shows the current code line, it hasn't been executed until you type next.
You probably pass an index that is larger than the number of columns in preview. Try:
p pcFolder
p preview->get_columns().size()

preview->get_column(); returns NULL, before that, its just some random value, since you didn't initialize the col variable

Better code would actually be to initialise the variable immediately on use by calling getColumn at the point of declaration:
TreeViewColumn *col = preview->get_column(pcFolder);
If this function can return NULL (as it appears to) you must then check before you use the pointer, thus:
if( col != NULL )
{
col->set_resizable( true );
}
// else handle the "error" if you want

preview->get_column(pcFolder)
must be returning 0.

Related

Why can't I assign an int to the union member of a struct member?

I'm trying to assign a value to the member of an union which is member of a struct, but the value doesn't seem to be assigned.
I've stepped through the program, and right after the assignation, len_param.data value seems to be some sort of pointer (see GDB output at the end of the post)
Also, if I printf, it runs normally:
len_param.data.v_int = 4;
// If I uncomment this line, IT RUNS FINE! WHY?
// printf("len_param.data.v_int: %i \n", len_param.data.v_int);
The type of len_param is as follow:
struct Parameter {
enum {
NORMAL, ARRAY, SKIP,
} type;
GIDirection direction;
GIArgument data;
};
And GIArgument definition:
union _GIArgument
{
gboolean v_boolean;
gint8 v_int8;
guint8 v_uint8;
gint16 v_int16;
guint16 v_uint16;
gint32 v_int32;
guint32 v_uint32;
gint64 v_int64;
guint64 v_uint64;
gfloat v_float;
gdouble v_double;
gshort v_short;
gushort v_ushort;
gint v_int;
guint v_uint;
glong v_long;
gulong v_ulong;
gssize v_ssize;
gsize v_size;
gchar * v_string;
gpointer v_pointer;
};
typedef _GIArgument GIArgument;
The complete file can be found here: https://gist.github.com/romgrk/642388914a9ff412eb5683fca44009d7#file-function-cc-L255
And my GDB output when I step at that line is:
Thread 1 "node" hit Breakpoint 1, GNodeJS::FunctionInvoker (info=...) at ../src/function.cc:256
256 len_param.data.v_int = GetV8ArrayLength(info[in_arg]);
(gdb) step
GNodeJS::GetV8ArrayLength (value=...) at ../src/function.cc:25
25 static int GetV8ArrayLength (Local<Value> value) {
(gdb) finish
Run till exit from #0 GNodeJS::GetV8ArrayLength (value=...) at ../src/function.cc:25
GNodeJS::FunctionInvoker (info=...) at ../src/function.cc:260
260 callable_arg_values[length_i].v_pointer = &len_param.data;
Value returned is $1 = 4
(gdb) p len_param.data.v_int
$2 = -17928
(gdb) p len_param
$3 = {
type = GNodeJS::Parameter::SKIP,
direction = GI_DIRECTION_INOUT,
data = {
v_boolean = -17928,
v_int8 = -8 '\370',
v_uint8 = 248 '\370',
v_int16 = -17928,
v_uint16 = 47608,
v_int32 = -17928,
v_uint32 = 4294949368,
v_int64 = 140737488337400,
v_uint64 = 140737488337400,
v_float = -nan(0x7fb9f8),
v_double = 6.9533558069492434e-310,
v_short = -17928,
v_ushort = 47608,
v_int = -17928,
v_uint = 4294949368,
v_long = 140737488337400,
v_ulong = 140737488337400,
v_ssize = 140737488337400,
v_size = 140737488337400,
v_string = 0x7fffffffb9f8 "\t\357\304\303J\a",
v_pointer = 0x7fffffffb9f8
}
}
The problem might be that nothing is ever done with len_param.data except to take its address just before it goes out of scope and the lifetime of len_param expires. So the compiler figures there's no point storing anything there.
Here's the code snippet where len_param is defined, used and dies (with unnecessary code elided and some annotation comments added):
if (param.type == Parameter::ARRAY) {
// ...
Parameter len_param = call_parameters[length_i]; // len_param is defined
if (len_param.direction == GI_DIRECTION_IN) {
// ...
}
else if (len_param.direction == GI_DIRECTION_INOUT) {
len_param.data.v_int = GetV8ArrayLength(info[in_arg]);
callable_arg_values[length_i].v_pointer = &len_param.data;
}
} // len_param goes out of scope, so it's no longer alive
// and the pointer that got placed in `callable_arg_values[length_i].v_pointer`
// is pointing to garbage
The root problem is that the pointer in callable_arg_values[length_i].v_pointer isn't valid moments after it gets stored.

shared pointer is shown as expired

While debugging a piece of code I see this on gdb:
(gdb) p *(input_t *) 0xec08b4d0
$25 = {
count = 0xec0644ec,
data = std::shared_ptr (expired, weak 0) 0xec0913ec,
}
Assignment to data leads to a crash. Is data an invalid pointer ?

The param was changed by passed to a function when I call the function

The function is defined like this:
1 db_bool cm_text_equal(const cm_text_t *text1, const cm_text_t *text2, db_bool case_ins)
and it will be called like this:
cm_format_element_t * cm_fetch_fmt_element(cm_text_t * fmt)
{
db_uint32 i;
cm_text_t cmp_text;
CM_POINTER(fmt);
cmp_text.str = fmt->str;
for(i = 0; i < DATE_FORMAT_COUNT; i++)
{
cmp_text.len = g_fmt_elements[i].name.len;
if(cmp_text.len > fmt->len)
{
continue;
}
//2 the problem happens here where the function be called
if(cm_text_equal(&g_fmt_elements[i].name, &cmp_text, DB_TRUE))
{
fmt->str += cmp_text.len;
fmt->len = (db_uint16)(fmt->len - cmp_text.len);
return &g_fmt_elements[i];
}
}
return NULL;
}
the g_fmt_elements[] is defined like this:
cm_format_element_t g_fmt_elements[DATE_FORMAT_COUNT] =
{
{{1, (db_char *)" "}, FMT_SPACE_SPLIT, DB_TRUE},
{{1, (db_char *)"-"}, FMT_MINUS_SPLIT, DB_TRUE},
...
}
typedef struct tagcm_format_element
{
cm_text_t name;
db_uint16 id;
db_bool reverse_used;
}cm_format_element_t;
typedef struct tagcm_text
{
db_uint32 len;
db_char * str;
}cm_text_t;
I debug the program by gdb. so before the function cm_text_equal called. the threee parameters are:
&g_fmt_elements[i].name = (cm_text_t *) 0x7f24f8766890
&cmp_text=0x7f2553ef8790
DB_TRUE=1
when cm_fetch_fmt_element is running to the line "//2 the problem...".
the i=30. and the variable g_fmt_elements is a global static variable.
you can see its definition below.
(gdb) p g_fmt_elements[30]
$57 = {name = {len = 4, str = 0x7f24f854a949 "YYYY"}, id = 226, reverse_used = 1}
(gdb) p &g_fmt_elements[30]
$58 = (cm_format_element_t *) 0x7f24f8766890
Then I step into the function cm_text_equal, and it turns out:
(gdb) s
cm_text_equal (text1=0x7f256ec655d0, text2=0x7f2553ef8790, case_ins=1) at src/db_text.c:504
so you can see, the first param was changed from 0x7f24f8766890 to 0x7f256ec655d0, and I check the regesters:
(gdb) p/x $rdi
$52 = 0x7f256ec655d0
(gdb) p/x $rsi
$53 = 0x7f2553ef8790
(gdb) p/x $rdx
$54 = 0x1
you can see the first param passed into the rdi was real changed. Does anyone know how that happend?
I also checked two different addrs.
(gdb) p *(cm_format_element_t*)0x7f256ec655d0
$55 = {name = {len = 4, str = 0x7f256ea6275c "YYYY"}, id = 226, reverse_used = 0}
(gdb) p *(cm_format_element_t*)0x7f24f8766890
$56 = {name = {len = 4, str = 0x7f24f854a949 "YYYY"}, id = 226, reverse_used = 1}
you see, 0x7f24f8766890 is the right addr and its value is the same as definition. while the other addr 0x7f256ec655d0 is wrong, but I don't understand its value almost the same as the right one. However the last member is wrong, which makes my program runs abnormally.
here is more details that I found later
thank you all for trying to help.
I guess I found where to be wrong.
It almost took me two days to figure out the reason, I am not good at. Haha.
but I just still want to answer it for others who may have the same problems.
Ok, let's begin.
Because I have restart my program, so the addr have changed. so this time
before step into the function. the add of g_fmt_elements[30] is:
(gdb) p g_fmt_elements[30]
$6 = {name = {len = 4, str = 0x2ae97faa554e "YYYY"}, id = 226, reverse_used = 1}
(gdb) p &g_fmt_elements[30]
$7 = (cm_format_element_t *) 0x2ae97fcc34d0
(gdb)
and after step into the function, the param text1 become to :
(gdb) cm_text_equal (text1=0x2ae90be468f0, text2=0x2ae926d85540, case_ins=1) at src/db_text.c:499
so, you see, the (cm_format_element_t *) 0x2ae97fcc34d0 seems to changed to text1=0x2ae90be468f0, so I also check these two addr's context:
//-->the right one
(gdb)p *(cm_format_element_t*)0x2ae97fcc34d0
{name = {len = 4, str = 0x2ae97faa554e "YYYY"}, id = 226, reverse_used = 1}
//-->the wrong one
(gdb)p *(cm_format_element_t*)0x2ae90be468f0
{name = {len = 4, str = 0x2ae90bc432e6"YYYY"}, id = 226, reverse_used = 0}
the two's context almost same but the values of "addr of str" and "reverse_used".
so, how exactly the wrong addr 0x2ae90be468f0 comes, and why the context is almost the same?
so, info the libs addr of the program and found which lib does the addr 0x2ae90be468f0 belonged to.

gdb class is incomplete type until I set breakpoint in class constructor?

I debug Chrome in gdb and I run into this problem all the time:
If I try to print a variable of certain type, GDB does not know its internals:
(gdb) p current_child_.get()
$12 = (blink::NGBlockNode *) 0xc2f755c1830
(gdb) p *(current_child_.get())
$13 = <incomplete type>
But, if I just set a breakpoint in a constructor of that class, gdb will suddenly discover that type's symbols:
(gdb) br blink::NGBlockNode::NGBlockNode
Breakpoint 3 at 0x51db40 (4 locations)
(gdb) p *(current_child_.get())
$14 = {
<blink::NGLayoutInputNode> = {
<blink::GarbageCollectedFinalized<blink::NGLayoutInputNode>> = {
<blink::GarbageCollected<blink::NGLayoutInputNode>> = {<No data fields>}, <No data fields>},
This is so annoying, I have a set of macros to set breakpoints in classes I usually print. Are there any other workarounds?
I know one workaround. If you know the file which defines the type, you can force loading debug information of that type, by "print 'file.cc'::some_variable". If this "some_variable" actually exists or not does not really matter.
e.g.
(gdb) p render_thread
$2 = (content::RenderThreadImpl *) 0x1261201f7920
(gdb) p *render_thread
$3 = <incomplete type>
(gdb) ptype render_thread
type = class content::RenderThreadImpl {
<incomplete type>
} *
(gdb) p 'render_thread_impl.cc'::nonexist_variable
No symbol "nonexist_variable" in specified context.
(gdb) ptype render_thread
type = /* real type = content::RenderThreadImpl * */
class content::RenderThreadImpl : <snipped> {
<snipped>
} *
(gdb) p *render_thread
$4 = (content::RenderThreadImpl) { <snipped> }
(gdb)
Turns out that the root cause is my compile flags: using gcc --gdb-index and --split-dwarf options together results in corrupt debug information. – Aleksandar Totic

How can I see how a C++ class gets laid out in memory with gdb?

I've got a debug build of a program (the V8 JavaScript VM) and I want to understand how instances of certain classes are laid out in memory. I can pretty-print structures like this:
(gdb) print thread_local
$6 = {
blocks_ = {
data_ = 0x868ceb0,
capacity_ = 7,
length_ = 1
},
entered_contexts_ = {
data_ = 0x868d828,
capacity_ = 1,
length_ = 1
},
saved_contexts_ = {
data_ = 0x868d838,
capacity_ = 1,
length_ = 1
},
spare_ = 0x0,
ignore_out_of_memory_ = false,
call_depth_ = 1,
handle_scope_data_ = {
next = 0x0,
limit = 0x0,
level = 0
}
}
but I want to know where those various members (blocks, entered_contexts, etc.) are physically, relative to the start of the object. On Solaris-based systems, mdb can do this for C structs like so:
> ::print -at port_event_t
0 port_event_t {
0 int portev_events
4 ushort_t portev_source
6 ushort_t portev_pad
8 uintptr_t portev_object
10 void *portev_user
}
In that example, each field is prefixed with its offset from the start of the structure. I want to do the same thing for C++ classes. gdb has to have this information in order to print out the struct members, but is there any way to view it?
Alternatively, is there some other way to do this for a running program?
You can always print out the address of each member and this to figure it out yourself (you use & to get the member address, just like in the language itself).
I wish I knew.
You can use ptype to list members. Then you can fabricate a poor man's offsetof like this:
(gdb) p/a &((my_struct_*)0)->my_member
(gdb) p/a &((struct sk_buff*)0)->iif
$7 = 0x74
In 2020, modern gdb versions have ptype /o:
(gdb) ptype /o 'sead::MethodTreeNode'
/* offset | size */ type = class sead::MethodTreeNode : public sead::IDisposer, public sead::TTreeNode<sead::MethodTreeNode*>, public sead::INamable {
private:
/* 88 | 32 */ class sead::StorageFor<sead::AnyDelegate> [with T = class sead::AnyDelegate] {
private:
/* 88 | 32 */ u8 mStorage[32];
/* total size (bytes): 32 */
} mDelegateHolder;
/* 120 | 8 */ class sead::CriticalSection *mCriticalSection;
/* 128 | 4 */ u32 mPriority;
/* 132 | 4 */ sead::BitFlag32 mPauseFlag;
/* 136 | 8 */ PauseEventDelegate *mPauseEventDelegate;
/* 144 | 8 */ void *mUserID;
/* total size (bytes): 152 */
}
It'll even show you the layout of member variables that are structs/classes and the total size.
For the record, this is the original C++ code:
class MethodTreeNode : public IDisposer, public TTreeNode<MethodTreeNode*>, public INamable
{
// ...
using PauseEventDelegate = IDelegate2<MethodTreeNode*, PauseFlag>;
// ...
StorageFor<sead::AnyDelegate> mDelegateHolder;
mutable CriticalSection* mCriticalSection;
u32 mPriority;
BitFlag32 mPauseFlag;
PauseEventDelegate* mPauseEventDelegate;
void* mUserID;
};
I haven't figured out how to make it print member offsets in hexadecimal, though...
The only way I know of is x /<number of bytes>x <variable name>
This will give you a hex dump then it is up to you to read the structure.
Use pahole (not part of GDB).
Another possibility is pahole.py (not yet committed).