mitchellh / virtualbox

[ABANDONED] Create and modify virtual machines in VirtualBox using pure ruby.
http://mitchellh.github.com/virtualbox/
MIT License
245 stars 45 forks source link

Out Arrays should be treated as pointers to sizeof(pointer), not pointers to sizeof(type) #71

Closed klynch closed 4 years ago

klynch commented 13 years ago

when constructing pointers for out arrays, a pointer of sizeof(void *) should be created, not of the size of the type.

When trying to read arrays of int32, ruby (64-bit on OSX) crashes because it tries to read an 8-byte pointer from a 4-byte value.

mitchellh commented 13 years ago

Hm, I'm not convinced this is correct (but I'm not convinced it is wrong either).

For example, the C header prototype for one function is this:

    nsresult (*EnumerateGuestProperties)(
        IMachine *pThis,
        PRUnichar * patterns,
        PRUint32 *nameSize,
        PRUnichar *** name,
        PRUint32 *valueSize,
        PRUnichar *** value,
        PRUint32 *timestampSize,
        PRInt64* timestamp,
        PRUint32 *flagsSize,
        PRUnichar *** flags
    );

The output for "name" for example is obviously a pointer to an array of pointers to PRUnichar. But the output for timestamp is actually just an array of PRInt64, not a pointer.

Currently, I believe the dragon code you've dove into does this correctly. Perhaps in your case the int32 type is just resolving to the wrong size.

klynch commented 12 years ago

Based on the few functions I have looked at from the C API, this was the only one that outputs an array to a single pointer. All of the others that I've seen are:

These make sense as usually in C you pass in a reference to your own pointer to store the array of Char*, the array of IntTypes, or the array of pointers to objects (I'm sure you know this, but I'm just outlining for both of our own sanity). This timestamp reference is the only one that seems different.

Interestingly, this particular function returns the same thing to for my modification as it does for yours and the VBoxManage interface.

Here is some output from my code with some debug output

ruby-1.9.2-p180 :003 > m.enumerate_guest_properties
FFI call: enumerate_guest_properties [:unicode_string, [:out, [:unicode_string]], [:out, [:unicode_string]], [:out, [:ulong]], [:out, [:unicode_string]]] [] [nil, #<FFI::MemoryPointer address=0x000001010237d0 size=4>, #<FFI::MemoryPointer address=0x000001010202d0 size=8>, #<FFI::MemoryPointer address=0x00000101030140 size=4>, #<FFI::MemoryPointer address=0x00000101024730 size=8>, #<FFI::MemoryPointer address=0x00000103416160 size=4>, #<FFI::MemoryPointer address=0x0000010136d900 size=8>, #<FFI::MemoryPointer address=0x0000010341da30 size=4>, #<FFI::MemoryPointer address=0x0000010135cc00 size=8>]
    = [nil, #<FFI::MemoryPointer address=0x000001010237d0 size=4>, #<FFI::MemoryPointer address=0x000001010202d0 size=8>, #<FFI::MemoryPointer address=0x00000101030140 size=4>, #<FFI::MemoryPointer address=0x00000101024730 size=8>, #<FFI::MemoryPointer address=0x00000103416160 size=4>, #<FFI::MemoryPointer address=0x0000010136d900 size=8>, #<FFI::MemoryPointer address=0x0000010341da30 size=4>, #<FFI::MemoryPointer address=0x0000010135cc00 size=8>]
    *** dereference_pointer_array : #<FFI::MemoryPointer address=0x000001010202d0 size=8> inferred_type unicode_string length 22
    *** dereference_pointer_array : #<FFI::MemoryPointer address=0x00000101024730 size=8> inferred_type unicode_string length 22
    *** dereference_pointer_array : #<FFI::MemoryPointer address=0x0000010136d900 size=8> inferred_type ulong length 22
    *** dereference_pointer_array : #<FFI::MemoryPointer address=0x0000010135cc00 size=8> inferred_type unicode_string length 22
    = [["/VirtualBox/HostGuest/SysprepExec", "/VirtualBox/HostGuest/SysprepArgs", "/VirtualBox/HostInfo/GUI/LanguageID", "/VirtualBox/GuestInfo/OS/Product", "/VirtualBox/GuestInfo/OS/Release", "/VirtualBox/GuestInfo/OS/Version", "/VirtualBox/GuestInfo/OS/ServicePack", "/VirtualBox/GuestAdd/Version", "/VirtualBox/GuestAdd/VersionExt", "/VirtualBox/GuestAdd/Revision", "/VirtualBox/GuestInfo/OS/LoggedInUsersList", "/VirtualBox/GuestInfo/OS/LoggedInUsers", "/VirtualBox/GuestInfo/OS/NoLoggedInUsers", "/VirtualBox/GuestInfo/Net/0/V4/IP", "/VirtualBox/GuestInfo/Net/0/V4/Broadcast", "/VirtualBox/GuestInfo/Net/0/V4/Netmask", "/VirtualBox/GuestInfo/Net/0/MAC", "/VirtualBox/GuestInfo/Net/0/Status", "/VirtualBox/GuestInfo/Net/Count", "/VirtualBox/HostInfo/VBoxVer", "/VirtualBox/HostInfo/VBoxVerExt", "/VirtualBox/HostInfo/VBoxRev"], ["", "", "en_US", "Linux", "3.0.0-12-server", "#20-Ubuntu SMP Fri Oct 7 16:36:30 UTC 2011", "", "4.1.4", "4.1.4", "74291", "aniketos", "1", "false", "10.0.2.15", "10.0.2.255", "255.255.255.0", "080027A314D6", "Up", "1", "4.1.4", "4.1.4", "74291"], [1319343088015914000, 1319343088016036000, 1319343864372154000, 1319343099052059000, 1319343099052509000, 1319343099052871000, 1319343099053219000, 1319343099053580000, 1319343099053921000, 1319343099054293000, 1319343099054668000, 1319343099055030000, 1319343099055372000, 1319343099056079000, 1319343099056428000, 1319343099056799000, 1319343099057163000, 1319343099057506000, 1319344399254669000, 1319343088016570000, 1319343088016605000, 1319343088016642000], ["TRANSIENT, RDONLYGUEST", "TRANSIENT, RDONLYGUEST", "", "", "", "", "", "", "", "", "TRANSIENT, TRANSRESET", "TRANSIENT, TRANSRESET", "TRANSIENT, TRANSRESET", "", "", "", "", "", "", "TRANSIENT, RDONLYGUEST", "TRANSIENT, RDONLYGUEST", "TRANSIENT, RDONLYGUEST"]]
 => [["/VirtualBox/HostGuest/SysprepExec", "/VirtualBox/HostGuest/SysprepArgs", "/VirtualBox/HostInfo/GUI/LanguageID", "/VirtualBox/GuestInfo/OS/Product", "/VirtualBox/GuestInfo/OS/Release", "/VirtualBox/GuestInfo/OS/Version", "/VirtualBox/GuestInfo/OS/ServicePack", "/VirtualBox/GuestAdd/Version", "/VirtualBox/GuestAdd/VersionExt", "/VirtualBox/GuestAdd/Revision", "/VirtualBox/GuestInfo/OS/LoggedInUsersList", "/VirtualBox/GuestInfo/OS/LoggedInUsers", "/VirtualBox/GuestInfo/OS/NoLoggedInUsers", "/VirtualBox/GuestInfo/Net/0/V4/IP", "/VirtualBox/GuestInfo/Net/0/V4/Broadcast", "/VirtualBox/GuestInfo/Net/0/V4/Netmask", "/VirtualBox/GuestInfo/Net/0/MAC", "/VirtualBox/GuestInfo/Net/0/Status", "/VirtualBox/GuestInfo/Net/Count", "/VirtualBox/HostInfo/VBoxVer", "/VirtualBox/HostInfo/VBoxVerExt", "/VirtualBox/HostInfo/VBoxRev"], ["", "", "en_US", "Linux", "3.0.0-12-server", "#20-Ubuntu SMP Fri Oct 7 16:36:30 UTC 2011", "", "4.1.4", "4.1.4", "74291", "aniketos", "1", "false", "10.0.2.15", "10.0.2.255", "255.255.255.0", "080027A314D6", "Up", "1", "4.1.4", "4.1.4", "74291"], [1319343088015914000, 1319343088016036000, 1319343864372154000, 1319343099052059000, 1319343099052509000, 1319343099052871000, 1319343099053219000, 1319343099053580000, 1319343099053921000, 1319343099054293000, 1319343099054668000, 1319343099055030000, 1319343099055372000, 1319343099056079000, 1319343099056428000, 1319343099056799000, 1319343099057163000, 1319343099057506000, 1319344399254669000, 1319343088016570000, 1319343088016605000, 1319343088016642000], ["TRANSIENT, RDONLYGUEST", "TRANSIENT, RDONLYGUEST", "", "", "", "", "", "", "", "", "TRANSIENT, TRANSRESET", "TRANSIENT, TRANSRESET", "TRANSIENT, TRANSRESET", "", "", "", "", "", "", "TRANSIENT, RDONLYGUEST", "TRANSIENT, RDONLYGUEST", "TRANSIENT, RDONLYGUEST"]] 

However, I am a little unsure how to parse these timestamps... 1319343088015914000 is far in the future, and it is reported the same by VBoxManage. Is this an issue for my host and/or guest or do you experience this too?