Skip to content

Large arrays getting corrupted. #3

@robgrimball

Description

@robgrimball

This may be a ref-struct issue, I am not sure. It appears to occur when the two are used together. But since I can create a linked list of ref-structs of the same size successfully without issue, I am guessing it is at least related to ref-array.

What I am doing is fairly simple. I create an array of structs that look like this :

var StringArray = ref_array('string');  

var HostInfo = ref_struct({
    snmpVersion: ref.types.int,
    address: ref.types.CString,
    mibs: StringArray,
    mibsLength: ref.types.int,
    username: ref.types.CString,
    secLevel: ref.types.int,
    authProto: ref.types.CString,
    privProto: ref.types.CString,
    authPhrase: ref.types.CString,
    privPhrase: ref.types.CString,
    doWalk: ref.types.int,
    repetitions: ref.types.int,
    showLabels: ref.types.int,
    showDescriptions: ref.types.int
});

The array is declared as so :

var hosts = new HostArray(inHosts.length);

Where inHosts is a javascript array of objects that will be populating the array as is done here :

for (var i=0; i<inHosts.length; i++) {
    var themibs = new StringArray(inHosts[i].mibs.length);

    for (var j=0; j<inHosts[i].mibs.length; j++) {
        themibs[j] = inHosts[i].mibs[j];
    }

    hosts[i] = new HostInfo({
        snmpVersion: inHosts[i].snmpVersion,
        address: inHosts[i].address,
        mibs: themibs,
        mibsLength: inHosts[i].mibs.length,
        username: inHosts[i].username,
        secLevel: inHosts[i].secLevel,
        authProto: inHosts[i].authProto,
        privProto: inHosts[i].privProto,
        authPhrase: inHosts[i].authPhrase,
        privPhrase: inHosts[i].privPhrase,
        doWalk: inHosts[i].doWalk,
        repetitions: (inHosts[i].repetitions) ? inHosts[i].repetitions : 0,
        showLabels: (inHosts[i].showLabels) ? 1 : 0,
        showDescriptions: (inHosts[i].showDescriptions) ? 1 : 0
    });
}

This array is then passed to a ffi function defined and executed as so :

var libsnmp_lib = ffi.Library('libsnmp_lib', {
    'do_snmp_query':[ref.refType(SessionInfo), [HostArray, 'int']],
});

var sessionInfoRef = libsnmp_lib.do_snmp_query(hosts, inHosts.length);

All that do_snmp_query does presently is loop through the array and look to see that the data is as expected. It does this by checking the username, which for the input data is all the same. If it finds something other than what it is expecting it prints out what it received for the host info.

When I do this with about 250 hosts, I get corruption of the array elements relatively frequently(if done ten times, I usually have at least one run with an instance of corruption, often a lot of it), seemingly most of it is the char *'s seem to get mangled and sent off who knows where. I say this since the printfs seem to still display the proper int values, but the strings are garbage.

When I do this with about 50 hosts, I have to run it a lot before I see an instance of corruption and usually it is just one record that is corrupted.

I was able to get around the whole issue altogether by making my array into a linked list, and that I ran 10000 times just to be sure no data corruption was occurring, so I am not entirely hamstrung by this issue, but there are cases where passing an array is far preferable to passing a linked list so I imagine that instances of data corruption like this are important to know about.

Again thanks for putting out such a great package!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions