Skip to content

usb library fails on Windows

I'm trying to get my Haskell usb library to work on Windows. I currently get a weird error. Please follow the steps below to reproduce the error:

  • Download libusb for Windows and extract it somewhere e.g. C:\Program Files\libusb\libusb1.

(Important build-time files: libusb-1.0\include\libusb.h and MinGW32\dll\libusb-1.0.dll.a)

(Important run-time files: MinGW32\dll\libusb-1.0.dll)

(This version lets you use the right calling convention on Windows (stdcall instead of ccall) by configuring cabal with cc-options: -DBINDINGS_STDCALLCONV)

  • Install bindings-libusb:
git clone git://github.com/basvandijk/bindings-libusb.git
cd bindings-libusb

Make sure to checkout the windows branch and let cabal know where to find libusb:

git checkout windows
cabal install --extra-include-dirs="C:\Program Files\libusb\libusb1\include\libusb-1.0" 
              --extra-lib-dirs="C:\Program Files\libusb\libusb1\MinGW32\dll"
  • Clone the usb repository:
git clone git://github.com/basvandijk/usb.git
cd usb

There's no need to install the library. I included an example program that will demonstrate the error:

cabal configure --flags="example -library"
cabal build

The example should read some bytes of an attached USB mouse (change the VID and PID to match your mouse). However it gives two errors:

dist\build\example\example.exe
example.exe: NotFoundException
Segmentation fault/access violation in generated code

This bug report is about the segmentation fault.

The NotFoundException is thrown by c'libusb_get_config_descriptor which is indirectly called by getDevices. According to the libusb docs this error is thrown when the specified configuration doesn't exists. Since I only call this function on existing configurations this seems like a bug in libusb. I will dive in the libusb source code to see what is going on.

The Segmentation fault/access violation in generated code is caused by the finalizer in newCtx:

newCtx ∷ IO Ctx
newCtx = newCtxNoEventManager Ctx

libusb_init ∷ IO (Ptr C'libusb_context)
libusb_init = alloca $ \ctxPtrPtr → do
               handleUSBException $ c'libusb_init ctxPtrPtr
               peek ctxPtrPtr

newCtxNoEventManager ∷ (ForeignPtr  C'libusb_context → Ctx) → IO Ctx
newCtxNoEventManager ctx = mask_ $ do
                            ctxPtr ← libusb_init
                            ctx <$> newForeignPtr p'libusb_exit ctxPtr

When p'libusb_exit is called the segmentation fault occurs.

'''Note that the error disappears when I change that last line with:

ctx <$> Foreign.Concurrent.newForeignPtr ctxPtr (c'libusb_exit ctxPtr)'''

I previously got the exact same segmentation fault when calling other bindings-libusb functions. This was caused by using the wrong calling convention on Windows. I used ccall but had to use stdcall. So I assume the current segmentation fault has something to do with the calling convention of FunPtrs.

Any ideas what is causing this? I would really like to solve it. It's the last step before releasing usb-1.0.

Thanks!

Trac metadata
Trac field Value
Version 7.0.3
Type Bug
TypeOfFailure OtherFailure
Priority normal
Resolution Unresolved
Component Compiler (FFI)
Test case
Differential revisions
BlockedBy
Related
Blocking
CC John Obbele john.obbele@gmail.com, Joris Putcuyps joris.putcuyps@gmail.com, Maurício Antunes mauricio.antunes@gmail.com
Operating system
Architecture
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information