PlistHandle Dispose System.System.AccessViolationException
karthikeyan1241997 opened this issue · 1 comments
karthikeyan1241997 commented
I am getting AccessViolationException When GC finializes PlistHandle or when i call plistHandle.Dispose(). Issue occurred in Windows 10(64 bit) running latest version. Targeting .NET framework 4.6.2
Here is the Statcktrace:
Unhandled Exception: System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
at iMobileDevice.Plist.PlistNativeMethods.plist_free(IntPtr plist)
at iMobileDevice.Plist.PlistApi.plist_free(IntPtr plist)
at iMobileDevice.Plist.PlistHandle.ReleaseHandle()
at System.Runtime.InteropServices.SafeHandle.InternalFinalize()
at System.Runtime.InteropServices.SafeHandle.Dispose(Boolean disposing)
at System.Runtime.InteropServices.SafeHandle.Finalize()
Code Causing this Exception:
lockdownError = Lockdown.lockdownd_get_value(lockdownClientHandle, null, null, out PlistHandle valuePlist);
if(lockdownError != LockdownError.Success)
{
Debug.WriteLine("Failed. Error:" + lockdownError);
continue;
}
Plist.plist_get_string_val(Plist.plist_dict_get_item(valuePlist, "DeviceName"), out string deviceName);
Plist.plist_get_string_val(Plist.plist_dict_get_item(valuePlist, "BuildVersion"), out string buildVersion);
Plist.plist_get_string_val(Plist.plist_dict_get_item(valuePlist, "SerialNumber"), out string serialNumber);
Plist.plist_get_string_val(Plist.plist_dict_get_item(valuePlist, "ProductType"), out string productType);
Plist.plist_get_string_val(Plist.plist_dict_get_item(valuePlist, "DeviceClass"), out string deviceClass);
karthikeyan1241997 commented
Seems issue is due to ValuePlist is disposed first before disposing the inner values handles. Exception can be avoided by manually disposing the inner plist data handles.
Updated sample:
PlistHandle deviceNameHandle = Plist.plist_dict_get_item(valuePlist, "DeviceName");
Plist.plist_get_string_val(deviceNameHandle, out string deviceName);
PlistHandle buildVersionHandle = Plist.plist_dict_get_item(valuePlist, "BuildVersion");
Plist.plist_get_string_val(buildVersionHandle, out string buildVersion);
PlistHandle serialNumberHandle = Plist.plist_dict_get_item(valuePlist, "SerialNumber");
Plist.plist_get_string_val(serialNumberHandle, out string serialNumber);
PlistHandle productTypeHandle = Plist.plist_dict_get_item(valuePlist, "ProductType");
Plist.plist_get_string_val(productTypeHandle, out string productType);
PlistHandle deviceClassHandle = Plist.plist_dict_get_item(valuePlist, "DeviceClass");
Plist.plist_get_string_val(deviceClassHandle, out string deviceClass);
// Dispose inner Plist handles before Releasing ValuePlist Handle so that
// System.AccessViolationException is avoided.
deviceNameHandle.Dispose();
buildVersionHandle.Dispose();
serialNumberHandle.Dispose();
productTypeHandle.Dispose();
deviceClassHandle.Dispose();