pothosware / SoapyRTLSDR

SoapySDR RTL-SDR Support Module
https://github.com/pothosware/SoapyRTLSDR/wiki
MIT License
125 stars 29 forks source link

Access Violation in SoapyRTLSDR on Windows 11 (PothosSDR installation) for Consecutive Runs #76

Open KeyserSoze-ND opened 1 day ago

KeyserSoze-ND commented 1 day ago

I'm encountering a Windows fatal exception: access violation errorwhen using SoapyRTLSDR on Windows 11 Home 64-bit. The crash occurs when trying to interact with the RTL-SDR device (NooElec R820T2 SDR & DVB-T) using SoapySDR, and it seems to be a bug in the SoapyRTLSDR implementation on Windows.

The crash happens silently, but after adding the Python faulthandlerlibrary, I was able to trace the exact point of failure.

Environment:

SoapySDRUtil output:

C:\PothosSDR>SoapySDRUtil --info
######################################################
##     Soapy SDR -- the SDR abstraction library     ##
######################################################

Lib Version: v0.8.1-PothosSDR-2021.07.25-vc16-x64
API Version: v0.8.0
ABI Version: v0.8
Install root: C:\PothosSDR
Search path:  C:\PothosSDR/lib/SoapySDR/modules0.8
Module found: C:\PothosSDR/lib/SoapySDR/modules0.8/airspyhfSupport.dll (0.2.0-d682533)
Module found: C:\PothosSDR/lib/SoapySDR/modules0.8/airspySupport.dll   (0.2.0-411f73e)
Module found: C:\PothosSDR/lib/SoapySDR/modules0.8/audioSupport.dll    (0.1.1-91080cb)
Module found: C:\PothosSDR/lib/SoapySDR/modules0.8/bladeRFSupport.dll  (0.4.1-70505a5)
Module found: C:\PothosSDR/lib/SoapySDR/modules0.8/HackRFSupport.dll   (0.3.3-8d2e7be)
Module found: C:\PothosSDR/lib/SoapySDR/modules0.8/IrisSupport.dll     (2020.02.0.1-f100723)
Module found: C:\PothosSDR/lib/SoapySDR/modules0.8/LMS7Support.dll     (20.10.0-a45e482d)
Module found: C:\PothosSDR/lib/SoapySDR/modules0.8/miriSupport.dll     (0.2.6-585c012)
Module found: C:\PothosSDR/lib/SoapySDR/modules0.8/netSDRSupport.dll   (0.1.0-51516db)
Module found: C:\PothosSDR/lib/SoapySDR/modules0.8/osmosdrSupport.dll  (0.2.6-585c012)
Module found: C:\PothosSDR/lib/SoapySDR/modules0.8/RedPitaya.dll       (0.1.1-3d576f8)
Module found: C:\PothosSDR/lib/SoapySDR/modules0.8/remoteSupport.dll   (0.6.0-c09b2f1)
Module found: C:\PothosSDR/lib/SoapySDR/modules0.8/rtlsdrSupport.dll   (0.3.2-53ee8f4)
Module found: C:\PothosSDR/lib/SoapySDR/modules0.8/sdrPlaySupport.dll  (0.3.0-206b241)
Module found: C:\PothosSDR/lib/SoapySDR/modules0.8/uhdSupport.dll      (0.4.1-9a738c3)
Module found: C:\PothosSDR/lib/SoapySDR/modules0.8/volkConverters.dll[WARNING] SoapyVOLKConverters: no VOLK config file found. Run volk_profile for best performance.
  (0.1.0-62ac7f5)
Available factories... airspy, airspyhf, audio, bladerf, hackrf, iris, lime, miri, netsdr, osmosdr, redpitaya, remote, rtlsdr, sdrplay, uhd
Available converters...
 -  CF32 -> [CF32, CF64, CS16, CS32, CS8, CU16, CU8]
 -  CF64 -> [CF32, CS16, CS32, CS8]
 -  CS16 -> [CF32, CF64, CS16, CS8, CU16, CU8]
 -  CS32 -> [CF32, CF64, CS32]
 -   CS8 -> [CF32, CF64, CS16, CS8, CU16, CU8]
 -  CU16 -> [CF32, CS16, CS8]
 -   CU8 -> [CF32, CS16, CS8]
 -   F32 -> [F32, F64, S16, S32, S8, U16, U8]
 -   F64 -> [F32, S16, S32, S8]
 -   S16 -> [F32, F64, S16, S8, U16, U8]
 -   S32 -> [F32, F64, S32]
 -    S8 -> [F32, F64, S16, S8, U16, U8]
 -   U16 -> [F32, S16, S8]
 -    U8 -> [F32, S16, S8]

The following python script can be used to reproduce the error:

import os
import ctypes
os.add_dll_directory(r'C:\PothosSDR\bin') # 
ctypes.windll.LoadLibrary(r'C:\PothosSDR\\bin\rtlsdr.dll') # 
import SoapySDR
import time
import faulthandler
faulthandler.enable()

def main():  
    args = {'driver': 'rtlsdr'}  
    sdr = SoapySDR.Device(args)
    sdr.setSampleRate(SoapySDR.SOAPY_SDR_RX, 0, 2.048e6)
    sdr.setFrequency(SoapySDR.SOAPY_SDR_RX, 0, 100e6)    
    stream = sdr.setupStream(SoapySDR.SOAPY_SDR_RX, SoapySDR.SOAPY_SDR_CF32)
    sdr.activateStream(stream)
    time.sleep(1) 
    sdr.deactivateStream(stream)
    sdr.closeStream(stream)
    print("Stream closed")
    time.sleep(1)

if __name__ == "__main__":    
    while True:
        main()

Expected behaviour: The program should run without crashing, and the SDR device should be properly deactivated and closed at each iteration.

Actual behaviour: The program crashes with a "Windows fatal exception: access violation error" in the SoapySDR.py library when closing the stream and cleaning up the SDR device. Here is the error traceback captured using faulthandler:

[WARNING] SoapyVOLKConverters: no VOLK config file found. Run volk_profile for best performance.
Found Rafael Micro R820T/2 tuner
[INFO] Opening Generic RTL2832U OEM :: df47a2b4edae...
Found Rafael Micro R820T/2 tuner
[INFO] Using format CF32.
Allocating 15 (non-zero-copy) user-space buffers
Stream closed
[INFO] Opening Generic RTL2832U OEM :: df47a2b4edae...
Found Rafael Micro R820T/2 tuner
[INFO] Using format CF32.
Allocating 15 (non-zero-copy) user-space buffers
Stream closed
[INFO] Opening Generic RTL2832U OEM :: df47a2b4edae...
Found Rafael Micro R820T/2 tuner
[INFO] Using format CF32.
Allocating 15 (non-zero-copy) user-space buffers
Stream closed
[INFO] Opening Generic RTL2832U OEM :: df47a2b4edae...
Found Rafael Micro R820T/2 tuner
[INFO] Using format CF32.
Allocating 15 (non-zero-copy) user-space buffers
Stream closed
[INFO] Opening Generic RTL2832U OEM :: df47a2b4edae...
Found Rafael Micro R820T/2 tuner
[INFO] Using format CF32.
Allocating 15 (non-zero-copy) user-space buffers
Stream closed
Windows fatal exception: access violation

Current thread 0x00000a0c (most recent call first):
  File "C:\Users\avioh\anaconda3\envs\rtlsdr-test-2\lib\site-packages\SoapySDR.py", line 1484 in unmake
  File "C:\Users\avioh\anaconda3\envs\rtlsdr-test-2\lib\site-packages\SoapySDR.py", line 1822 in close
  File "C:\Users\avioh\anaconda3\envs\rtlsdr-test-2\lib\site-packages\SoapySDR.py", line 1825 in __del__
  File "c:\icarus\simple_test.py", line 25 in <module>

Additional Information:

Possible Cause:

Please let me know if you need further information, and I can provide more details.

zuckschwerdt commented 1 day ago

This smells like a double-free. For a quick fix note that closeStream will also deactivateStream and that dropping the reference to Device will also closeStream implicitly -- you should be okay to just del sdr. edit: actually __del__ will close and that in turn will unmake (as seen in the trace), streams are not implicitly closed. Strange then where unmake fails. SoapyRTLSDR's destructor has nothing but a rtlsdr_close(dev) call.

KeyserSoze-ND commented 1 day ago

I tried the following:

def main():  
    args = {'driver': 'rtlsdr'}  
    sdr = SoapySDR.Device(args)
    sdr.setSampleRate(SoapySDR.SOAPY_SDR_RX, 0, 2.048e6)
    sdr.setFrequency(SoapySDR.SOAPY_SDR_RX, 0, 100e6)    
    stream = sdr.setupStream(SoapySDR.SOAPY_SDR_RX, SoapySDR.SOAPY_SDR_CF32)
    sdr.activateStream(stream)
    time.sleep(1) 
    #sdr.deactivateStream(stream)
    sdr.closeStream(stream)
    print("Stream closed")
    time.sleep(1)

if __name__ == "__main__":    
    while True:
        main()

This fails the same way.

I also tried this:

def main():  
    args = {'driver': 'rtlsdr'}  
    sdr = SoapySDR.Device(args)
    sdr.setSampleRate(SoapySDR.SOAPY_SDR_RX, 0, 2.048e6)
    sdr.setFrequency(SoapySDR.SOAPY_SDR_RX, 0, 100e6)    
    stream = sdr.setupStream(SoapySDR.SOAPY_SDR_RX, SoapySDR.SOAPY_SDR_CF32)
    sdr.activateStream(stream)
    time.sleep(1) 
    del sdr
    print("Stream closed")
    time.sleep(1)

if __name__ == "__main__":    
    while True:
        main()

Interestingly, this does not crash but just hangs. The python kernel stops responding. (CTRL+C does not work etc.)

zuckschwerdt commented 1 day ago

I guess the first example might keep the sdr Device around and the second tries to force a close with an active stream, which won't work as the rtlsdr async is still running. All around your examples are valid and what should be expected to work from a Python perspective.

There are no clues why the unmake would fail after some tries. We likely need to try if this also appears in a similar C example and then debug the state, perhaps with gcc. I'll try to run this code on Linux and see if it can be reproduced. I hope it's not some Windows pecularity.

zuckschwerdt commented 2 hours ago

I can reproduce this in Linux, seems to be particular to Windows or your setup. Do you have WSL? Can you reproduce this in WSL? Are you up to trying the same example in C? That would make out or exclude Python as the culprit.

KeyserSoze-ND commented 32 minutes ago

I do not have WSL but VSCode has an extension for it so I will try to reproduce this in WSL. I never used this library in C but I can also try this with C while I am at it.