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
857 stars 459 forks source link

[C#] [ReportControlBlock] The methods (SetTrgOps / SetOptFlds) throwing System.AccessViolationException #25

Closed IgorMundstein closed 6 years ago

IgorMundstein commented 6 years ago

Hi,

I am testing the reports. I used the sample projects on dotnet solution

image

image

System.AccessViolationException was unhandled HResult=-2147467261 Message=Attempted to read or write protected memory. This is often an indication that other memory is corrupt. Source=iec61850dotnet StackTrace: at IEC61850.Client.ReportControlBlock.ClientReportControlBlock_setTrgOps(IntPtr self, Int32 trgOps) at IEC61850.Client.ReportControlBlock.SetTrgOps(TriggerOptions trgOps) at Debugger.IEC61850v2.Program.Main(String[] args) in C:\Tests\IEC61850\Program.cs:line 118 at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args) at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() at System.Threading.ThreadHelper.ThreadStart_Context(Object state) at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart() InnerException:

I realized that the exception is only thrown if the program executes the method GetRCBValues (Image 1 line 3). If this method is not executed. There is no exception and the command works perfectly.

It does not appear to be an error in communication or protocol. Since the SetRCBValues method is not even executed. I believe the problem is in the ReportControlBlock object.

mzillgith commented 6 years ago

I tried this with the 64 bit compiled native DLL and the examples I have for reporting ("reporting" and "report_new_dataset" and the problem doesn't show. Have you tried the examples? Do they also show the problem for you? Maybe in your code the connection doesn't work and "self" is a NULL pointer?

IgorMundstein commented 6 years ago

@mzillgith

I recorded a video: https://youtu.be/95Hi23AczaQ

IgorMundstein commented 6 years ago

Hi @mzillgith,

I found a way to work.

Call the methods: SetOptFlds and SetTrgOps BEFORE the method GetRCBValues and the exception will not be thrown.

Probably, the method GetRCBValues must be blocking some memory access lock.

mzillgith commented 6 years ago

Hi @IgorMundstein , I have seen in your video that the RCB reference uses the "$" as separator, while the examples are using the "." as separator. In fact the GetReportControlBlock method assumes the "." signs in the reference and cannot detect if it is an buffered report when using the "$" signs. Because the GetRCBValues function later assumes it is an unbuffered RCB where the elements are slightly different the memory gets corrupted. When you are using "DemoProtCtrl/LLN0.BR.brcb02" as reference it should work. I know it is a bit confusing that the "." signs have to be used for the RCB reference while the "$" for the data set reference in the RCB. I will change the code so it will accept both types of separators.

IgorMundstein commented 6 years ago

@mzillgith

I did not realize it. I am used to remove FunctionalConstraint from address and replace $ to .

Like I do in the method "ReadValue", for example. However, it have the parameter (FunctionalConstraint ) in the signature.

Thanks!