Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OSError with wxPython #203

Closed
JoshMayberry opened this issue Jun 13, 2018 · 16 comments
Closed

OSError with wxPython #203

JoshMayberry opened this issue Jun 13, 2018 · 16 comments
Labels

Comments

@JoshMayberry
Copy link

If I try to find the USB devices in a wxPython window, I get the following error:

Exception ignored in: <bound method _AutoFinalizedObjectBase.__del__ of <usb.backend.libusb1._Device object at 0x04307210>>
Traceback (most recent call last):
  File "C:\Users\guest\AppData\Local\Programs\Python\Python36-32\lib\site-packages\usb\_objfinalizer.py", line 84, in __del__
    self.finalize()
  File "C:\Users\guest\AppData\Local\Programs\Python\Python36-32\lib\site-packages\usb\_objfinalizer.py", line 144, in finalize
    self._finalizer()
  File "C:\Users\guest\AppData\Local\Programs\Python\Python36-32\lib\weakref.py", line 548, in __call__
    return info.func(*info.args, **(info.kwargs or {}))
  File "C:\Users\guest\AppData\Local\Programs\Python\Python36-32\lib\site-packages\usb\_objfinalizer.py", line 104, in _do_finalize_object_ref
    obj._do_finalize_object()
  File "C:\Users\guest\AppData\Local\Programs\Python\Python36-32\lib\site-packages\usb\_objfinalizer.py", line 71, in _do_finalize_object
    self._finalize_object()
  File "C:\Users\guest\AppData\Local\Programs\Python\Python36-32\lib\site-packages\usb\backend\libusb1.py", line 604, in _finalize_object
    _lib.libusb_unref_device(self.devid)
OSError: exception: access violation writing 0x00000014
^C

Here is some simple code that can create the error.

import wx
import usb

class MyForm(wx.Frame):
	def __init__(self):
		wx.Frame.__init__(self, None, wx.ID_ANY, "Example")
		panel = wx.Panel(self, wx.ID_ANY)
		sizer = wx.BoxSizer(wx.VERTICAL)

		button = wx.Button(panel, label="Run test()")
		button.Bind(wx.EVT_BUTTON, self.test)
		
		sizer.Add(button, 0, wx.ALL|wx.CENTER, 5)
		panel.SetSizer(sizer)

	def test(self, event):
		valueList = []
		devices = usb.core.find(find_all=True)
		for config in devices:
			valueList.append((config.idVendor, config.idProduct))
		print(valueList)

		event.Skip()

if __name__ == "__main__":
	app = wx.App(False)
	frame = MyForm()
	frame.Show()
	app.MainLoop()

To produce the error, press the button "Run test()" in the frame that appears after running the code.

@JoshMayberry
Copy link
Author

I also get a similar error by running the show_devices() function in usb.core

Exception ignored in: <bound method _AutoFinalizedObjectBase.__del__ of <usb.backend.libusb1._Device object at 0x03BDDB10>>
Traceback (most recent call last):
  File "C:\Users\guest\AppData\Local\Programs\Python\Python36-32\lib\site-packages\usb\_objfinalizer.py", line 84, in __del__
    self.finalize()
  File "C:\Users\guest\AppData\Local\Programs\Python\Python36-32\lib\site-packages\usb\_objfinalizer.py", line 144, in finalize
DEVICE ID 05f9:4204 on Bus 001 Address 056, Communications Device
DEVICE ID 045e:07b2 on Bus 001 Address 007, Specified at interface
DEVICE ID 046d:c62b on Bus 001 Address 002, Specified at interface
DEVICE ID 058f:9254 on Bus 001 Address 008, Hub
DEVICE ID 8086:a12f on Bus 001 Address 000, Hub
    self._finalizer()
  File "C:\Users\guest\AppData\Local\Programs\Python\Python36-32\lib\weakref.py", line 548, in __call__
    return info.func(*info.args, **(info.kwargs or {}))
  File "C:\Users\guest\AppData\Local\Programs\Python\Python36-32\lib\site-packages\usb\_objfinalizer.py", line 104, in _do_finalize_object_ref
    obj._do_finalize_object()
  File "C:\Users\guest\AppData\Local\Programs\Python\Python36-32\lib\site-packages\usb\_objfinalizer.py", line 71, in _do_finalize_object
    self._finalize_object()
  File "C:\Users\guest\AppData\Local\Programs\Python\Python36-32\lib\site-packages\usb\backend\libusb1.py", line 604, in _finalize_object
    _lib.libusb_unref_device(self.devid)
OSError: exception: access violation writing 0x00000014

This code is what produces this error.

import usb
print(usb.core.show_devices())

@mcuee
Copy link
Member

mcuee commented Aug 1, 2018

libusb/libusb#412

Issue reported here.

@mcuee
Copy link
Member

mcuee commented Aug 1, 2018

C:\work\pyusb>type listall.py
import usb
print(usb.core.show_devices())

C:\work\pyusb>python listall.py
Exception ignored in: <bound method _AutoFinalizedObjectBase.__del__ of <usb.backend.libusb1._Device object at 0x03B9F230>>
Traceback (most recent call last):
  File "C:\Python36-32\lib\site-packages\usb\_objfinalizer.py", line 84, in __del__
    self.finalize()
  File "C:\Python36-32\lib\site-packages\usb\_objfinalizer.py", line 144, in finalize
    self._finalizer()
  File "C:\Python36-32\lib\weakref.py", line 548, in __call__
    return info.func(*info.args, **(info.kwargs or {}))
  File "C:\Python36-32\lib\site-packages\usb\_objfinalizer.py", line 104, in _do_finalize_object_ref
    obj._do_finalize_object()
  File "C:\Python36-32\lib\site-packages\usb\_objfinalizer.py", line 71, in _do_finalize_object
    self._finalize_object()
  File "C:\Python36-32\lib\site-packages\usb\backend\libusb1.py", line 604, in _finalize_object
    _lib.libusb_unref_device(self.devid)
OSError: exception: access violation writing 0x00000014
DEVICE ID 1c7a:0570 on Bus 001 Address 003, Specified at interface
DEVICE ID 8086:9d2f on Bus 001 Address 000, Hub
DEVICE ID 8087:0a2a on Bus 001 Address 004, Wireless Controller
DEVICE ID 046d:c52f on Bus 001 Address 002, Specified at interface
DEVICE ID 04f2:b5f7 on Bus 001 Address 001, Miscellaneous
DEVICE ID 04d8:fa2e on Bus 001 Address 006, Specified at interface
DEVICE ID 0bda:0129 on Bus 001 Address 005, Vendor-specific


C:\work\pyusb>python --version
Python 3.6.5

@mcuee
Copy link
Member

mcuee commented Aug 1, 2018

Temporary workaround is to go back to libusb-1.0.21 where this issues does not manifest itself.

C:\work\pyusb>python listall.py
DEVICE ID 1c7a:0570 on Bus 001 Address 004, Specified at interface
DEVICE ID 8086:9d2f on Bus 001 Address 001, Specified at interface
DEVICE ID 04f2:b5f7 on Bus 001 Address 002, Miscellaneous
DEVICE ID 8087:0a2a on Bus 001 Address 005, Wireless Controller
DEVICE ID 046d:c52f on Bus 001 Address 003, Specified at interface
DEVICE ID 04f2:b5f7 on Bus 001 Address 002, Miscellaneous
DEVICE ID 04d8:fa2e on Bus 001 Address 007, Specified at interface
DEVICE ID 0bda:0129 on Bus 001 Address 006, Vendor-specific

@mcuee
Copy link
Member

mcuee commented Aug 1, 2018

Or you can use libusb0 backend (libusb-win32). Take note libusb-win32 will only list the device which uses libusb-win32 compatible driver (libusb0.sys or libusbk.sys).


C:\work\pyusb>type listall_libusb0.py
import usb
from usb.backend import libusb0
b = usb.backend.libusb0.get_backend()
print(usb.core.show_devices(backend=b))

C:\work\pyusb>python listall_libusb0.py
DEVICE ID 04d8:fa2e on Bus 000 Address 255, Specified at interface

@dickens
Copy link

dickens commented Aug 3, 2018

See comment in libusb/libusb#412. This is not a libusb issue.

The refcounting mechanism in pyusb is broken. The above log shows debug messages added within the ref/unref functions of libusb and the init/_finalize_object methods of pyusb. You can see that the _LibUSB backend object was finalized before all of the _Device objects were finalized. The warning from libusb during libusb_exit() even says "some libusb_devices were leaked". Applications are not allowed to reference a device after its context has been destroyed.

@mcuee mcuee added the windows label Aug 7, 2018
@chisaipete
Copy link

So, it looks like this is a pyusb issue, is there any word on a fix?

@JoshMayberry
Copy link
Author

@mcuee How are things going with a fix for this error?

minkustree added a commit to minkustree/pyusb that referenced this issue Dec 23, 2018
Each call to libusb1's get_backend returns a new _LibUSB object.
When each  _LibUSB object falls out of scope, it calls ends up
calling libusb_exit() which deinitializes libusb, even if there are still
references in scope.

Practically speaking, pyusb seems to assume there's only one
context active, so returning the same _LibUSB object on
subsequent calls to get_backend should prevent there from being
more than one call to libusb_exit() when backend objects go
out of scope.

This should fix errors where the libusb library was being used after
libusb_exit() had been called.
jonasmalacofilho added a commit to liquidctl/liquidctl that referenced this issue Nov 17, 2019
The patch for PyUSB successfully prevents access violation errors during
cleanup with libusb 1.0.22, but "some libusb_devices were leaked"
warnings can still be seen with LIBUSB_DEBUG=3.

Patch: 8041ec11b2c4 ("Fix #203: libusb sometimes cleaned up too early.")
Related: pyusb/pyusb#227 ("Fix #203: libusb sometimes cleaned up too early.")
Related: pyusb/pyusb#203 ("OSError with wxPython #203")
@mcuee mcuee closed this as completed in f644ea7 Nov 25, 2019
@mcuee mcuee reopened this Nov 30, 2019
@mcuee mcuee removed the blocker label Nov 30, 2019
@mcuee
Copy link
Member

mcuee commented Nov 30, 2019

Maybe the following can help.

Ref: eblot/pyftdi#121
eblot commented:

I found a weird behaviour in pyusb: when the port is indirectly closed right after the port is open, some kind of race condition in pyusb/libusb lets it to re-open the closed device to perform the cleanup action, which triggers a native exception in libusb. This has been worked around in the latest PyFtdi patch version (v0.30.1), so that no cleanup action is performed when the existing pyusb handle is not longer existing. This prevents the pyusb resource manager to re-open the device in such event.

@mcuee
Copy link
Member

mcuee commented Dec 7, 2019

With the latest git, it seems to be okay, with latest libusb Windows.

$ python --version
Python 3.8.0

$ cat listall.py
import usb
print(usb.core.show_devices())

$ python listall.py
DEVICE ID 8086:27cb on Bus 001 Address 000, Hub
DEVICE ID 0bda:5411 on Bus 004 Address 007, Hub
DEVICE ID 0bda:0411 on Bus 004 Address 002, Hub
DEVICE ID 0bda:5411 on Bus 004 Address 003, Hub
DEVICE ID 0a5c:21e8 on Bus 006 Address 005, Vendor-specific
DEVICE ID 05e3:0749 on Bus 004 Address 006, Specified at interface
DEVICE ID 1a40:0201 on Bus 006 Address 004, Hub
DEVICE ID 0ac8:3420 on Bus 004 Address 008, Miscellaneous
DEVICE ID 0b95:1790 on Bus 004 Address 005, Vendor-specific
DEVICE ID 8086:27ca on Bus 005 Address 000, Hub
DEVICE ID 046d:c52b on Bus 006 Address 003, Specified at interface
DEVICE ID 2357:0106 on Bus 004 Address 001, Specified at interface
DEVICE ID 0fcf:1009 on Bus 002 Address 001, Specified at interface
DEVICE ID 8086:27cc on Bus 006 Address 000, Hub
DEVICE ID 058f:6366 on Bus 006 Address 002, Specified at interface
DEVICE ID 1a40:0201 on Bus 006 Address 001, Hub
DEVICE ID 8086:27c9 on Bus 003 Address 000, Hub
DEVICE ID 1033:0194 on Bus 004 Address 000, Hub
DEVICE ID 0bda:0411 on Bus 004 Address 004, Hub
DEVICE ID 8086:27c8 on Bus 002 Address 000, Hub

@mcuee
Copy link
Member

mcuee commented Dec 7, 2019

No issues with wxusb.py either when I press the button.

C:\work\pyusb\test>python wxusb.py
[(4047, 4105)]
[(4047, 4105)]
[(4047, 4105)]
[(4047, 4105)]
[(4047, 4105)]
[(4047, 4105)]
[(4047, 4105)]
[(4047, 4105)]
[(4047, 4105)]
[(4047, 4105)]
[(4047, 4105)]
[(4047, 4105)]
[(4047, 4105)]

@mcuee
Copy link
Member

mcuee commented Dec 7, 2019

@JoshMayberry
Probably #227 fixed this issue.

Please check on your side. Thanks.

@JoshMayberry
Copy link
Author

@mcuee
Thank you for remembering this issue after so long. You all are doping a wonderful job! And congratulations for finding the fix!

After using the latest version from the github, the problem was solved (No OSError when I ran the script I provided at the top of this issue).

This fix is not, however, in the latest version on pypi.org.

@jonasmalacofilho
Copy link
Member

@JoshMayberry

This fix is not, however, in the latest version on pypi.org.

I understand (including from my own experience) that this is an annoying issue for downstream projects. I'll try to get a release ready soon, even if some other issues end up missing the cut.

@akbyrd
Copy link

akbyrd commented May 18, 2020

Any word on a release?

@jonasmalacofilho
Copy link
Member

I delayed the release because a few (unconfirmed but suspect) unrelated issues have surfaced.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants