TooTallNate / ref-struct

Create ABI-compliant "struct" instances on top of Buffers
119 stars 75 forks source link

self referencing struct issue #3

Open rhasson opened 12 years ago

rhasson commented 12 years ago

when creating a struct where one or more of its members are pointers to the same struct and used with node-ffi these nested structs are filled in with invalid memory addresses so dereferencing them causes a seg fault.

Example structs:

var pst_index_ll = Struct ({
    'i_id': 'uint64',
    'offset': 'uint64',
    'size': 'uint64',
    'u1': 'int64'
});
pst_index_ll.defineProperty('next', ref.refType(pst_index_ll));

var pst_desc_tree = Struct ({
    'd_id': 'uint64',
    'parent_d_id': 'uint64',
    'no_child': 'int32'
});
pst_desc_tree.defineProperty('desc', ref.refType(pst_index_ll));
pst_desc_tree.defineProperty('assoc_tree', ref.refType(pst_index_ll));
pst_desc_tree.defineProperty('prev', ref.refType(pst_desc_tree));
pst_desc_tree.defineProperty('next', ref.refType(pst_desc_tree));
pst_desc_tree.defineProperty('parent', ref.refType(pst_desc_tree));
pst_desc_tree.defineProperty('child', ref.refType(pst_desc_tree));
pst_desc_tree.defineProperty('child_tail', ref.refType(pst_desc_tree));

In this example accessing "next" or "child", etc. would result in a seg fault because the memory address stored at these offsets in the buffer are invalid.

Thanks, Roy

TooTallNate commented 12 years ago

Struct instances start of with undefined data (this is true in C as well). You must initialize the struct, either manually or through other means like node-ffi, before accessing the data from it.

The problem you're describing is true for any "pointer" type, but the solution is simple: don't access uninitialized fields. If this were C, the compiler would be giving you a warning ;)

rhasson commented 12 years ago

Before passing these structs to a function (via node-ffi) I initialize them by doing tree = new pst_desc_tree(); The challenge is that within the C library the nested struct pointers are allocated and filled in correctly, but when that pointer is passed back to node-ffi I get an invalide memory address.

Am I not initializing the structs correctly? Do I need to initialize each of the nested structs as well?

Can you give an example of manually initializing the structs?

TooTallNate commented 12 years ago

Can you show me some of your example ffi code?

rhasson commented 12 years ago

https://github.com/rhasson/node-libpst/blob/master/ffi_nodepst.js

TooTallNate commented 12 years ago

Cool, and do you have a test script that uses that and crashes?

rhasson commented 12 years ago

any time I try to access any of the nested structs inside the instantiated pst_file struct called "f". That means when I try to do f.d_head.d_id for example would cause a seg fault.

In the file on github I try to copy the memory address from the instantiated buffer into another buffer and try to read it but that also fails. I would ignore that bit of code since I don't think it's even correct.