Author Topic: System.AccessViolationException was unhandled  (Read 4033 times)

Offline zach.green

  • Newbie
  • *
  • Posts: 11
  • Karma: 0
System.AccessViolationException was unhandled
« on: June 01, 2015, 08:47:25 PM »
I am receiving the following error when my application closes:

System.AccessViolationException was unhandled
Message: An unhandled exception of type 'System.AccessViolationException' occurred in wcl.dll
Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

This error seems very similar to this issue, but I can't tell from this topic what the resolution is: http://forum.btframework.com/index.php/topic,1923.msg6660.html#msg6660.

On creation of my app, I initialize my adapter like so:

       
        public WclAdapter()
        {
            _wclApi = new wclAPI();
            _wclApi.Load();

            _wclBluetoothDiscovery = new wclBluetoothDiscovery();
            _wclBluetoothDiscovery.OnDiscoveryStarted += wclBluetoothDiscovery_OnDiscoveryStarted;
            _wclBluetoothDiscovery.OnDiscoveryComplete += async (sender, args) => await wclBluetoothDiscovery_OnDiscoveryComplete(sender, args);
            _wclBluetoothDiscovery.OnDeviceFound += async (sender, args) => await wclBluetoothDiscover_OnDeviceFound(sender, args);
            _wclBluetoothDiscovery.OnDeviceLost += async (sender, args) => await wclBluetoothDiscover_OnDeviceLost(sender, args);
        }


On exit, I call the following:

        public void Shutdown()
        {
            _isShuttingDown = true;

            _wclApi.Unload();

            _wclBluetoothDiscovery.Dispose();
            _wclApi.Dispose();
        }


Any ideas to what would cause this error? I am using version 6.14.3.0.

Thanks.
Zach Green

Offline Mike Petrichenko

  • Bluetooth Framework Developer
  • Administrator
  • Hero Member
  • *****
  • Posts: 3053
  • Karma: 1000
    • Soft Service Company
Re: System.AccessViolationException was unhandled
« Reply #1 on: June 01, 2015, 09:47:58 PM »
Hello,

You can not use async await with WCL events.

Offline zach.green

  • Newbie
  • *
  • Posts: 11
  • Karma: 0
Re: System.AccessViolationException was unhandled
« Reply #2 on: June 01, 2015, 09:49:43 PM »
Removing async/await has no affect on the problem.

Offline zach.green

  • Newbie
  • *
  • Posts: 11
  • Karma: 0
Re: System.AccessViolationException was unhandled
« Reply #3 on: June 01, 2015, 10:01:36 PM »
Is it possible this is related to me trying to use this in a WPF application? Is the library supported in WPF?

Offline Mike Petrichenko

  • Bluetooth Framework Developer
  • Administrator
  • Hero Member
  • *****
  • Posts: 3053
  • Karma: 1000
    • Soft Service Company
Re: System.AccessViolationException was unhandled
« Reply #4 on: June 01, 2015, 10:02:37 PM »
Removing async/await has no affect on the problem.

Would be great to see event handlers code. Problem may be there.

Offline Mike Petrichenko

  • Bluetooth Framework Developer
  • Administrator
  • Hero Member
  • *****
  • Posts: 3053
  • Karma: 1000
    • Soft Service Company
Re: System.AccessViolationException was unhandled
« Reply #5 on: June 01, 2015, 10:04:19 PM »
Is it possible this is related to me trying to use this in a WPF application? Is the library supported in WPF?

In fact we have never tested it but I do not see any reason why it can not. I think WCL should work with WPF

Offline zach.green

  • Newbie
  • *
  • Posts: 11
  • Karma: 0
Re: System.AccessViolationException was unhandled
« Reply #6 on: June 01, 2015, 10:12:33 PM »
Seems strange that these event handlers would affect an error thrown when I close the app. Below is most of the life cycle from constructor and events. The scancallback basically just saves some info to the db, and then calls connect if the device was previously connected.



        public WclAdapter()
        {
            _wclApi = new wclAPI();
            _wclApi.Load();

            _wclBluetoothDiscovery = new wclBluetoothDiscovery();
            _wclBluetoothDiscovery.OnDiscoveryStarted += wclBluetoothDiscovery_OnDiscoveryStarted;
            _wclBluetoothDiscovery.OnDiscoveryComplete += wclBluetoothDiscovery_OnDiscoveryComplete;
            _wclBluetoothDiscovery.OnDeviceFound += wclBluetoothDiscover_OnDeviceFound;
            _wclBluetoothDiscovery.OnDeviceLost += wclBluetoothDiscover_OnDeviceLost;
        }

        public void Connect(string address, int messageSize, Action onConnected, Action<byte[]> onMessage, Action<BluetoothError> onError)
        {
            //fire connecting event
            if (Connecting != null)
            {
                Connecting(this, new DeviceStatusEventArgs { Address = address });
            }


            //try to clear client if it exists already
            if (_clients.ContainsKey(address))
            {
                wclClient client;
                if (!_clients.TryRemove(address, out client))
                {
                    if (Error != null)
                    {
                        Error(this, new DeviceStatusEventArgs { Address = address, Message = "Unable to clear old bluetooth client." });
                    }
                }
            }

            //setup call backs
            var bc = new wclClient();
            if (!_clients.TryAdd(address, bc))
            {
                if (Error != null)
                {
                    Error(this, new DeviceStatusEventArgs { Address = address, Message = "Unable to save new bluetooth client." });
                }
            }

            bc.OnDisconnect += (sender, args) =>
            {
                if (Disconnected != null && !_isShuttingDown)
                {
                    Disconnected(this, new DeviceStatusEventArgs { Address = address });
                }
            };

            bc.OnData += (sender, args) =>
            {
                //buffer data till full message received
                foreach (var b in args.Data)
                {
                    _buffer.Add(b);
                    if (b != Convert.ToByte('\n') || _buffer.Count != messageSize)
                    {
                        continue;
                    }

                    onMessage(_buffer.ToArray());
                    _buffer.Clear();
                }
            };

            bc.OnConnect += (sender, args) =>
            {
                //if it didn't complete, bounce it back to disconnect
                if (args.Error != wclErrors.WCL_E_SUCCESS)
                {
                    if (Error != null)
                    {
                        Error(this, new DeviceStatusEventArgs { Address = address, Message = wclErrors.wclGetErrorMessage(args.Error) });
                    }

                    bc.Disconnect();
                    return;
                }

                //fire connected event
                if (Connected != null)
                {
                    Connected(this, new DeviceStatusEventArgs { Address = address });
                }
            };

            //start connection
            var radio = GetSelectedRadio(_wclBluetoothDiscovery);
            if (radio != null)
            {
                bc.BluetoothParams.Address = string.Format("({0})", address);
                bc.BluetoothParams.Radio = radio;
                bc.BluetoothParams.Service = wclUUIDs.SerialPortServiceClass_UUID;
                bc.Transport = wclTransport.trBluetooth;
                bc.ConnectTimeout = 30000; //ms
                var errorCode = bc.Connect();
               
                //if it didn't complete, bounce it back to disconnect
                if (errorCode != wclErrors.WCL_E_SUCCESS)
                {
                    if (Error != null)
                    {
                        Error(this, new DeviceStatusEventArgs { Address = address, Message = wclErrors.wclGetErrorMessage(errorCode) });
                    }

                    bc.Disconnect();
                }
            }
        }

        public void StartScan(IScanCallback scanCallback, bool toggleRadios = true)
        {
            WriteDiagnosticEntryAction("Beginning scan of devices");
            IsScanning = true;
            if (ScanStarted != null)
            {
                ScanStarted(this, EventArgs.Empty);
            }

            ScanCallback = scanCallback;

            var radio = GetSelectedRadio(_wclBluetoothDiscovery);
            if (radio != null)
            {
                var errorCode = _wclBluetoothDiscovery.Discovery(radio);

                if (errorCode != wclErrors.WCL_E_SUCCESS)
                {
                    if (ScanError != null)
                    {
                        ScanError(this, new ScanErrorEventArgs { Message = wclErrors.wclGetErrorMessage(errorCode) });
                    }
                }
            }
        }

        private wclBluetoothRadio GetSelectedRadio(wclBluetoothDiscovery discovery)
        {
            wclBluetoothRadio radio = null;
            var radios = new wclBluetoothRadios();
            if (discovery.EnumRadios(radios) == wclErrors.WCL_E_SUCCESS && radios.Count > 0)
            {
                radio = new wclBluetoothRadio();
                radio.Assign(radios[0]);
            }
            if (radio == null)
            {
                if (Error != null)
                {
                    Error(this, new DeviceStatusEventArgs { Address = null, Message = "No Bluetooth API was found." });
                }
            }
            return radio;
        }

        private void wclBluetoothDiscovery_OnDiscoveryComplete(object sender, wclBluetoothDiscoveryCompleteEventArgs e)
        {
            if (ScanCallback != null)
            {
                var count = e.Devices.Count;
                var devices = new List<WclDevice>((int)count);
                for (var i = 0U; i < count; i++)
                {
                    string name = null;
                    e.Devices.GetName(e.Radio, ref name);
                    devices.Add(new WclDevice(name, e.Devices.Address.Replace("(", string.Empty).Replace(")", string.Empty), 0, new byte[] { }));
                }

                foreach (var device in devices)
                {
                    ScanCallback.Callback(device);
                }
            }

            WriteDiagnosticEntryAction("Completed scan of devices");
            IsScanning = false;
            if (ScanCompleted != null)
            {
                ScanCompleted(this, EventArgs.Empty);
            }
        }

        private void wclBluetoothDiscovery_OnDiscoveryStarted(object sender, wclBluetoothDiscoveryStartedEventArgs e)
        {
            IsScanning = true;
            if (ScanStarted != null)
            {
                ScanStarted(this, EventArgs.Empty);
            }
        }

        private void wclBluetoothDiscover_OnDeviceLost(object sender, wclBluetoothDiscoveryDeviceEventArgs args)
        {
            WriteDiagnosticEntryAction(string.Format("Device Lost, {0}", args.Device.Address));
        }

        private void wclBluetoothDiscover_OnDeviceFound(object sender, wclBluetoothDiscoveryDeviceEventArgs args)
        {
            WriteDiagnosticEntryAction(string.Format("Device Found, {0}", args.Device.Address));
        }

Offline Mike Petrichenko

  • Bluetooth Framework Developer
  • Administrator
  • Hero Member
  • *****
  • Posts: 3053
  • Karma: 1000
    • Soft Service Company
Re: System.AccessViolationException was unhandled
« Reply #7 on: June 01, 2015, 10:20:43 PM »
Possible problem is here

var count = e.Devices.Count;

in OnDiscoveryComplete event handler.

If discovering is active when you close your application e.devices is NULL.

Also

e.Devices.GetName(e.Radio, ref name);

should look like

e.Devices.GetName(e.Radio, ref name);

Offline zach.green

  • Newbie
  • *
  • Posts: 11
  • Karma: 0
Re: System.AccessViolationException was unhandled
« Reply #8 on: June 01, 2015, 10:29:39 PM »
Added a check for null on e.Devices; no change.

I noticed your demo apps all fire the Trial warning on close of the app, but mine doesn't. I am not sure if that is a result of the error, or if the error is occurring when the library is trying to open the warning.

Offline zach.green

  • Newbie
  • *
  • Posts: 11
  • Karma: 0
Re: System.AccessViolationException was unhandled
« Reply #9 on: June 01, 2015, 10:31:20 PM »
Also, I don't see a difference in the two lines of your comment:

Also

e.Devices.GetName(e.Radio, ref name);

should look like

e.Devices.GetName(e.Radio, ref name);



Thanks for all of your help.

Offline Mike Petrichenko

  • Bluetooth Framework Developer
  • Administrator
  • Hero Member
  • *****
  • Posts: 3053
  • Karma: 1000
    • Soft Service Company
Re: System.AccessViolationException was unhandled
« Reply #10 on: June 01, 2015, 10:33:32 PM »
Added a check for null on e.Devices; no change.

I noticed your demo apps all fire the Trial warning on close of the app, but mine doesn't. I am not sure if that is a result of the error, or if the error is occurring when the library is trying to open the warning.

Send me your code to mike@btframework.com. I'll find the bug. The problem that when you call wclAPI.Unload it shows dialog and closes all connections/terminates all operations/destroys object. So the problem appears in one of event handler. It is hard to find the bug without all the code.

Offline Mike Petrichenko

  • Bluetooth Framework Developer
  • Administrator
  • Hero Member
  • *****
  • Posts: 3053
  • Karma: 1000
    • Soft Service Company
Re: System.AccessViolationException was unhandled
« Reply #11 on: June 01, 2015, 10:34:21 PM »
Also, I don't see a difference in the two lines of your comment:

Also

e.Devices.GetName(e.Radio, ref name);

should look like

e.Devices.GetName(e.Radio, ref name);



Thanks for all of your help.

I think that is a forum problem :) Should be Devices [ i ] but forum deleted [ i ] in your and in my code (I think).

Offline zach.green

  • Newbie
  • *
  • Posts: 11
  • Karma: 0
Re: System.AccessViolationException was unhandled
« Reply #12 on: June 01, 2015, 10:38:03 PM »
Yes it did. The index into the array is in my code.

Sending all the code isn't real simple. This is a Xamarin project in which I have an iOS, Android, and WPF UI for a single PCL implementation. The project also uses MVVMCross to handle cross platform implementation features. For example, I am testing out your library as our WPF implementation for Bluetooth. Without a Xamarin license, I don't know that you can open project. I'll have to see if I can create a project tomorrow that shows the issue without the Xamarin integration.

Offline Mike Petrichenko

  • Bluetooth Framework Developer
  • Administrator
  • Hero Member
  • *****
  • Posts: 3053
  • Karma: 1000
    • Soft Service Company
Re: System.AccessViolationException was unhandled
« Reply #13 on: June 01, 2015, 10:47:27 PM »
May be then just a part which uses WCL? At least I can review it. The problem may apper when you call wclAPI.Unload. This method terminates all active WCL operations and after that call WCL objects become invalid. Also some events may fire (such us OnDiscoveryComplete, OnConnect, OnDisconnect). After that application terminates and GC disposes object. That may cause AV. I already saw such issue in other projects so problem can be in just one code line.

But all that happens after Trial Dialog appeared.

The other possible problem is your wrapper. If you do not dispose your wrapper when your application closes it will be disposed by GC. But application already closed/partially disposed and wclAPI.Unload cause the AV by reasons I described above.

Offline zach.green

  • Newbie
  • *
  • Posts: 11
  • Karma: 0
Re: System.AccessViolationException was unhandled
« Reply #14 on: June 02, 2015, 01:39:34 PM »
Ok. I am guessing it is probably something in the order of operations. I'll try to track down if I am leaving something open. The full source of my WclAdapter is attached. This is where all of the WCL code resides.

 

Sitemap 1 2 3 4 5 6 7 8 9