mz-automation / libiec61850

Official repository for libIEC61850, the open-source library for the IEC 61850 protocols
http://libiec61850.com/libiec61850
GNU General Public License v3.0
828 stars 444 forks source link

GetDataSetDirectoryAsync got System.AccessViolationException #498

Open Tivaty opened 3 months ago

Tivaty commented 3 months ago

Hello,

Evinronment: C# Lib version 1.5.3

When I set MaxPduSize to 1000 app crash happens. The reason I need to set it to 1000 to GetLogicalDeviceVariablesAsync without problem of timeout. When the value of MaxPduSize is larger than 1000 IED timeout error happens frequently.

IedConnection con = new IedConnection();
con.MaxPduSize = 1000; // GetDataSetDirectoryAsync and GetDataSetDirectory Failed

`System.AccessViolationException HResult=0x80004003 Message=Attempted to read or write protected memory. This is often an indication that other memory is corrupt. Source= StackTrace:

` Untitled
mzillgith commented 3 months ago

In what function does the application crash? Do you have a stack trace?

Tivaty commented 3 months ago

In what function does the application crash? Do you have a stack trace?

Hi, This is C# library so there is no stacktrace, only error message.

App crashed at "con.GetDataSetDirectoryAsync"

string dsRef = dataSetRef.Replace('$', '.');
Debug.WriteLine(dsRef);
waitForCallBack.Reset();
con.GetDataSetDirectoryAsync(dsRef, delegate (uint invokeId, object parameter, IedClientError err, List<string> dataSetDirectory, bool isDeletable)
{
    if (dataSetDirectory != null)
    {
        foreach (var doName in dataSetDirectory)
        {
            Debug.WriteLine("\t" + doName);
        }
    }
    else
    {
        Debug.WriteLine("Get dataset directory error: " + err.ToString());
    }
    waitForCallBack.Set();
}, null);
waitForCallBack.WaitOne(); 
Tivaty commented 3 months ago

Please note that, when con.MaxPduSize does not set. (default value 65000) this function works well. And I have 2 dataset LLN0$PROT1 have much more variable than LLN0$PROT2.

mzillgith commented 3 months ago

I found an issue with the .NET wrapper when the server doesn't send a response but an error message instead. Could this be the case here? I guess the dataset is too big to fit into a the small MMS PDU size and the server is sending an error message instead.

Tivaty commented 3 months ago

I found an issue with the .NET wrapper when the server doesn't send a response but an error message instead. Could this be the case here? I guess the dataset is too big to fit into a the small MMS PDU size and the server is sending an error message instead.

You are correct. And the issue I want to point out is the dataset is too big to fit into a the small MMS PDU size. In the GetNameListHandler there is a bool moreFollow. But with GetDataSetDirectoryHandler there is only isDeletable.

the reason PDU size is 1000 is for GetNameListHandler work well, when PDU larger than 1000 I got many IED timeout with my test.

mzillgith commented 3 months ago

There is no way to send a larger dataset when the MMS size is too small. Only the getnamelist MMS service supports splitting the response in multiple MMS messages.

But the issue (crash) should be resolved with this fix: https://github.com/mz-automation/libiec61850/commit/681d1b0e05e83bf6d45e42b66c9c780df3f40415

Tivaty commented 3 months ago

There is no way to send a larger dataset when the MMS size is too small. Only the getnamelist MMS service supports splitting the response in multiple MMS messages.

But the issue (crash) should be resolved with this fix: 681d1b0

Okay. Thank youuuu. Let me try again with the latest source code