0

I'm having a problem with the release version of my program. When I start it on my computer, everything works fine. There are no exceptions, no problems or any other stuff that stops me from working with the program. As soon as I zip the exe and its required DLLs and send it to a friend, he instantly receives the error ".exe has stopped working" when he tries to run the server.

By the way it's an opc server built with "open62541". When running, it retrieves values out of a PLC by the use of a library called "Snap7". And yes, he's located in the same network as I am, hence the reason cannot be the network connection.

We both are using windows and my IDE is Visual Studio 2015. Unfortunately, I cannot really post any code here because it's way too much. Moreover I wouldn't really know which code to post since I don't know where and why the error comes up.

EDIT: Here's my code where I get the exception. It's always thrown when "UA_Server_addVariableNode" is called.

for (int i = 0; i < 4; ++i)
{
    UA_VariableAttributes attrAttr;
    UA_VariableAttributes_init(&attrAttr);
    UA_QualifiedName attrBrowseName;
    UA_QualifiedName_init(&attrBrowseName);

    switch (i)
    {
    case 0: //Setting the ip-address
        UA_Variant_setScalar(&attrAttr.value, &UA_STRING(currentPlc.ip), &UA_TYPES[UA_TYPES_STRING]);
        attrAttr.displayName = UA_LOCALIZEDTEXT("en_US", "IPAddress");
        attrBrowseName = UA_QUALIFIEDNAME(1, "IPAddress");

        //Add the PLC value to the PLC-ObjectType
        UA_Server_addVariableNode(server, UA_NODEID_NULL, newPlcId,
            UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT),
            attrBrowseName,
            UA_NODEID_NULL, attrAttr, NULL, &isAvailableNodeId);
        break;

    case 1: //Setting the rack
        UA_Variant_setScalar(&attrAttr.value, &currentPlc.rack, &UA_TYPES[UA_TYPES_INT32]);
        attrAttr.displayName = UA_LOCALIZEDTEXT("en_US", "Rack");
        attrBrowseName = UA_QUALIFIEDNAME(1, "Rack");

        //Add the PLC value to the PLC-ObjectType
        UA_Server_addVariableNode(server, UA_NODEID_NULL, newPlcId,
            UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT),
            attrBrowseName,
            UA_NODEID_NULL, attrAttr, NULL, &isAvailableNodeId);
        break;

    case 2: //Setting the slot
        UA_Variant_setScalar(&attrAttr.value, &currentPlc.slot, &UA_TYPES[UA_TYPES_INT32]);
        attrAttr.displayName = UA_LOCALIZEDTEXT("en_US", "Slot");
        attrBrowseName = UA_QUALIFIEDNAME(1, "Slot");

        //Add the PLC value to the PLC-ObjectType
        UA_Server_addVariableNode(server, UA_NODEID_NULL, newPlcId,
            UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT),
            attrBrowseName,
            UA_NODEID_NULL, attrAttr, NULL, &isAvailableNodeId);
        break;

    case 3: //Setting "isAvailable" to give information about the PLC's status
        UA_Variant_setScalar(&attrAttr.value, &isAvailable, &UA_TYPES[UA_TYPES_BOOLEAN]);
        attrAttr.displayName = UA_LOCALIZEDTEXT("en_US", "isAvailable");
        attrBrowseName = UA_QUALIFIEDNAME(1, "isAvailable");

        //Add the PLC value to the PLC-ObjectType
        UA_Server_addVariableNode(server, UA_NODEID_NULL, newPlcId,
            UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT),
            attrBrowseName,
            UA_NODEID_NULL, attrAttr, NULL, &isAvailableNodeId);
        break;
    }
}
Stefan Profanter
  • 6,458
  • 6
  • 41
  • 73
Pete Hilde
  • 659
  • 1
  • 10
  • 24
  • Google gave me this, maybe it helps? http://windows7themes.net/en-us/how-to-fix-exe-has-stopped-working-in-windows-7/ – Galik Mar 31 '17 at 06:53
  • If a debug build doesn't crash, but the release build does, you can try adding a manual log file system to the release build, log as the program goes through major function areas. You can perhaps narrow down the area that's crashing then isolate exactly what was happening and values of variables at the time. Maybe you need some extra checking for null values or try/catch around some of the library functions. – Jason Lang Mar 31 '17 at 07:00
  • @Galik Thanks for searching but it didn't work...Still the same error. I should mention that the error does not come up when starting the programm. You first need to press enter two times in order to validate and parse an xml file. Afterwards, the actual opc server gets started. And this is where the error comes up! – Pete Hilde Mar 31 '17 at 07:02
  • It's REALLY not a great solution, and may not be viable, but have you tried installing and running it on VS 2015 on that other machine? When I have had these kind of problems, it usually turned out to be completely extraneous from the original problem, but installing/running VS, I was able to find the problem, though as a last ditch effort. – SteveFerg Mar 31 '17 at 07:31
  • @Jason Lang I actually tried out some try/catch expressions and I found the location where the exception is thrown. Now I get an access violation exception reading location "0x00000001". I think it's a problem with a null-pointer... but I really don't know how to fix it since the exception doesn't always come up, just sometimes..it almost seems like a Heisenbug to me.. – Pete Hilde Mar 31 '17 at 07:40
  • @SteveFerg Yep, I just tried your solution on the other machine and I get the same error/exception as mentioned in the comment to Jason Lang before – Pete Hilde Mar 31 '17 at 07:41
  • When you say you ship the "required dlls" I assume that includes the [Visual C++ Redistributable for Visual Studio 2015](https://www.microsoft.com/en-us/download/details.aspx?id=48145) - you need those installed to be able to run an application built using VS. – Jesper Juhl Mar 31 '17 at 07:49
  • @JesperJuhl It's installed on both machines. I don't think that this is the problem as other applications of VS2015 work without any problems ... – Pete Hilde Mar 31 '17 at 07:51
  • I really don't get it... Even if I set a breakpoint after the method is called, it's sometimes triggered and everything works fine and other times it throws an access violation before triggering the breakpoint at all... – Pete Hilde Mar 31 '17 at 07:58
  • That's why I said to put in logging. Narrow down the exact line of code where it fails, then print out the values. Probably an uninitialized pointer or something. i.e. it's reading random memory. Which *mostly* has a zero in it, in which case it works fine, but sometimes is non-zero, so slips through. e.g. if you have a check for null pointer in a library, but you give an unitialized pointer to it, it will sometimes be null and treated properly, but non-null other times, thus error. – Jason Lang Mar 31 '17 at 08:28

1 Answers1

0

I solved the problem after doing some research inside the "open62541" header.

In case 0 I use the expression "&UA_STRING(currentPlc.ip)" in the "UA_Variant_setScalar" function which I thought returns the equivalent UA_String of "currentPlc.ip".

But it actually returns a temporary object that is deleted after the function is called. As a result, the actual address of the object is null, hence I get an access violation. I simply added one line in which I pass the returned object to a variable and then use the address of the variable.

case 0: //Setting the ip-address
        auto value = UA_STRING(currentPlc.ip);
        UA_Variant_setScalar(&attrAttr.value, &value, &UA_TYPES[UA_TYPES_STRING]);
        attrAttr.displayName = UA_LOCALIZEDTEXT("en_US", "IPAddress");
        attrBrowseName = UA_QUALIFIEDNAME(1, "IPAddress");

        //Add the PLC value to the PLC-ObjectType
        UA_Server_addVariableNode(server, UA_NODEID_NULL, newPlcId,
            UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT),
            attrBrowseName,
            UA_NODEID_NULL, attrAttr, NULL, &isAvailableNodeId);
        break;
Pete Hilde
  • 659
  • 1
  • 10
  • 24