fventuri / gr-sdrplay3

Out-of-tree GNU Radio module for SDRplay RSP devices - SDRplay API V3.X
GNU General Public License v3.0
45 stars 7 forks source link

Problem with `dynamic initializer for 'antennas' #2

Open gvanem opened 3 years ago

gvanem commented 3 years ago

First off, I'm a bit confused whether this is the last / most up-to-date version of this block.

But my issue building this on Win-10 using MSVC, was plainly this C++ exception (from CDB after generating rsp1.py):

ModLoad: 5c790000 5c809000   f:\gv\dx-radio\gnuradio\gv-build\lib\site-packages\sdrplay3\sdrplay3_python.pyd
ModLoad: 5c970000 5c9b6000   f:\gv\dx-radio\gnuradio\gv-build\bin\gnuradio-sdrplay3.dll
ModLoad: 5ca00000 5ca0b000   f:\gv\dx-radio\gnuradio\gv-build\bin\sdrplay_api.dll
ModLoad: 74510000 745b3000   C:\WINDOWS\WinSxS\x86_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.30729.9619_none_508d9c7abcbd32b6\MSVCR90.dll
(db0.d08): C++ EH exception - code e06d7363 (first chance)
(db0.d08): C++ EH exception - code e06d7363 (!!! second chance !!!)
eax=0084e278 ebx=0084e328 ecx=00000003 edx=00000000 esi=69f014a0 edi=5c9ab8dc
eip=769b46d2 esp=0084e278 ebp=0084e2d4 iopl=0         nv up ei pl nz ac pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200216
KERNELBASE!RaiseException+0x62:
769b46d2 8b4c2454        mov     ecx,dword ptr [esp+54h] ss:002b:0084e2cc=ea1bd2d3

At first (when running w/o the debugger), I thought it had something to do with mixing CRTs; MSVCR90.dll in SDRPLAY_API.dll and vcruntime140.dll in my Python 3.6. But no. The ugly call-stack (deep inside a Python-call) shows it:

....
(Inline) -------- gnuradio_sdrplay3!std::map<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,
gr::sdrplay3::_antenna,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,gr::sdrplay3::_antenna> > >::{ctor}+0x4a
0084e480 75fb9b77 gnuradio_sdrplay3!gr::sdrplay3::`dynamic initializer for 'antennas''(void)+0x19f

Since you had 3 equally named struct _antenna, I renamed them to become unique (struct _antenna_rsp1, etc.). That seemed to have fixed it. No crash from MSVC's STL-code. I have a RSP1A which works fine.

Edit: my patch:

--- a/rsp2_impl.cc 2020-12-18 11:27:05
+++ b/rsp2_impl.cc 2020-12-18 15:10:34
@@ -33,12 +33,12 @@

 // Antenna methods
-struct _antenna {
+struct _antenna_rsp2 {
     sdrplay_api_Rsp2_AntennaSelectT select;
     bool high_z;
 };

-static const std::map<std::string, struct _antenna> antennas = {
+static const std::map<std::string, struct _antenna_rsp2> antennas = {
     { "Antenna A", { sdrplay_api_Rsp2_ANTENNA_A, false } },
     { "Antenna B", { sdrplay_api_Rsp2_ANTENNA_B, false } },
     { "Hi-Z",      { sdrplay_api_Rsp2_ANTENNA_A, true } }
--- a/rspduo_impl.cc 2020-12-18 11:27:05
+++ b/rspduo_impl.cc 2020-12-18 15:09:55
@@ -107,12 +107,12 @@

 // Antenna methods
-struct _antenna {
+struct _antenna_duo {
     sdrplay_api_TunerSelectT tuner;
     bool high_z;
 };

-static const std::map<std::string, struct _antenna> antennas = {
+static const std::map<std::string, struct _antenna_duo> antennas = {
     { "Tuner 1 50 ohm", { sdrplay_api_Tuner_A,    false } },
     { "Tuner 2 50 ohm", { sdrplay_api_Tuner_B,    false } },
     { "High Z",         { sdrplay_api_Tuner_A,    true } },
--- a/rspdx_impl.cc 2020-12-18 11:27:05
+++ b/rspdx_impl.cc 2020-12-18 15:10:15
@@ -33,11 +33,11 @@

 // Antenna methods
-struct _antenna {
+struct _antenna_dx1 {
     sdrplay_api_RspDx_AntennaSelectT select;
 };

-static const std::map<std::string, struct _antenna> antennas = {
+static const std::map<std::string, struct _antenna_dx1> antennas = {
     { "Antenna A", { sdrplay_api_RspDx_ANTENNA_A } },
     { "Antenna B", { sdrplay_api_RspDx_ANTENNA_B } },
     { "Antenna C", { sdrplay_api_RspDx_ANTENNA_C } }
fventuri commented 3 years ago

@gvanem first of all thanks for opening this issue and for your feedback.

To answer your question, this version is for GNU Radio 3.9 (and future versions), while the module in the 'gr-sdrplay' repo (branch 'API3+RSPduo') is for GNU Radio 3.7. As far as I can tell (and remember since I worked on them several months ago) there's not much difference in functionality between the two modules; it all depends on which version of GNU Radio you are currently using.

Also I developed (and built) them on Linux using the gcc compiler, so I am not surprised that a different compiler like MSVC generates different errors.

I am really glad that you found out what caused that crash and how to fix it; I'll make the same changes to the code in the repo, so it won't happen to other people using MSVC.

Also since you are probably the first person that built and successfully ran this GNU Radio module with Windows10 and MSVC, do you mind sharing what commands did you use? Here on Linux I used 'cmake ..' and 'make'; I was wondering if they work in Windows 10 too, or if you had to do something else; this way I can add your instructions and suggestions for Windows 10 in the README file.

One last question: I assume that you are running GNU Radio 3.9 since you are using this module; if this is the case, did you compile GNU Radio 3.9 yourself directly from the source code in github using MSVC? (the only instructions I found for Windows were for GNU Radio 3.8, if I remember correctly)

Thanks again, Franco

gvanem commented 3 years ago

do you mind sharing what commands did you use?

I started with CMake 5 years ago, but failed and feeled it was clumsy. So I then created some GNU-makefiles to build most of GnuRadio. Also for this module. So I do not know if your CMakeLists.txt will work for Windows/MSVC. But it does not seems very gcc/POSIX centric. It should work using cmake -G "NMake Makefiles" ... But trying this here now, there are far too many missing .cmake files.

I assume that you are running GNU Radio 3.9 since you are using this module;

Yes, I only work with one GR version; master. Which I built using MSVC and/or clang-cl. I did not pay attention to any instructions in the manual. Sorry I cannot be of more help for Windows build etc.

But the issue with dynamic initialiser, seems all three initialisers were merged into one. And when the loader called it the 2nd time, I got a stack-fault (or similar?). Building with clang-cl, the crash is different!? Gotta love this mess with C++..

fventuri commented 3 years ago

I just sync'd up with the latest commit from GNU Radio master, built it, rebuilt this gr-sdrplay3 module from scratch (using gcc, since that's the default), and, since I have an RSP2 here, I ran the very simple 'rsp2.grc' flowgraph (in the 'examples' folder) using GRC without any errors.

I also rebuilt just the module using Clang 11.0.0 (using the command CC=/usr/bin/clang CXX=/usr/bin/clang++ cmake ..; see here: https://github.com/fventuri/gr-sdrplay3/issues/1#issuecomment-731776812); however when I try to run that module compiled with clang using GNU Radio compiled with gcc, it fails with this error message:

Traceback (most recent call last):
  File "/usr/local/lib64/python3.9/site-packages/sdrplay3/__init__.py", line 24, in <module>
    from .sdrplay3_python import *
ImportError: generic_type: type "rsp" referenced unknown base type "gr::sync_block"

Perhaps I would have to recompile all of GNU Radio with clang (as opposed to gcc), but it is going to take too long.

I also have a Windows10 VM that I used to play with SDRuno to understand how the RSP2 works; I'll give it a try to see if I can build GNU Radio 3.9 first and then this module using the latest MSVC; this way I should be able to reproduce the 'dynamic initializer' error here, and try to figure out what's going on.

I'll send you an update about my progress.

Franco

gvanem commented 3 years ago

Another problem just happened after (I think), in converting rsp1a.grc to rsp1a.py and running it:

Traceback (most recent call last):
  File "rsp1a.py", line 203, in <module>
    main()
  File "rsp1a.py", line 179, in main
    tb = top_block_cls()
  File "rsp1a.py", line 106, in __init__
    window.WIN_BLACKMAN_hARRIS, #wintype
NameError: name 'window' is not defined
gr::log :INFO: rsp1a0 - total samples: [0,0]
fventuri commented 3 years ago

@gvanem I spent some time today trying to build GNU Radio 3.9 (the master branch) on Windows 10 using Visual Studio 2019 Community Edition; I was able to build 'volk', however with 'gnuradio' itself there are many dependencies (to give you an idea, take a look at the the list in this page: https://www.castle.cloud/gnuradio-for-windows/download/) that need to be built and installed before building GNU Radio - I was able to resolve a few of them today (Boost, pybind11), but I am afraid it will be a while before I can help you; my next one is 'log4cpp', where I think I'll have to use a NuGet package (is that wh rsp1a.zip at you did too?). I am also writing down a document with all my steps and the rationale behind the most important of them (and it is starting to get pretty long), so other people don't have to figure out everything from scratch.

Regarding the error message you are seeing NameError: name 'window' is not defined, I just ran gnuradio-companion to generate the Python script from the rsp1a.grc example, and I see that the name 'window' is defined in line 31 in the Python script rsp1a.py:

from gnuradio.fft import window

To help you troubleshoot this problem, I am also attaching the 'rsp1a.py' Python script that gets generated on my Linux computer here, so you can compare it with yours (I am not really sure why it says 'GNU Radio version: v3.8.0.0-843-g6d6c9a25' in line 12, since I have only GNU radio 3.9 installed here).

Franco

rsp1a.zip

gvanem commented 3 years ago

.. next one is 'log4cpp', where I think I'll have to use a NuGet package (is that what you did too?).

No, I downloaded it, did a cd msvc\log4cppLIB and ran msbuild log4cppLIB.vcxproj. But you could do a vcpkg install log4cpp x64-windows-static (or x64-..). VCPKG is available here.

To help you troubleshoot this problem, I am also attaching the 'rsp1a.py'

--- mine-rsp1a.py  2020-12-19 21:38:28
+++ yours-rsp1a.py 2020-12-19 23:23:16
@@ -9,7 +9,7 @@
 # Author: Franco Venturi
 # Copyright: Franco Venturi
 # Description: RSP1A test
-# GNU Radio version: 3.9.0
+# GNU Radio version: v3.8.0.0-843-g6d6c9a25

 from distutils.version import StrictVersion

@@ -28,6 +28,7 @@
 from gnuradio.filter import firdes
 import sip
 from gnuradio import gr
+from gnuradio.fft import window
 import sys
 import signal
 from argparse import ArgumentParser

The diff is due to change of <GR-root>/share/gnuradio/grc/blocks/options.block.yml. I have that change, but grcc seemed to pick-up the other <GR-root>/lib/site-packages/gnuradio/grc/blocks/options.block.yml which is not in GRC_BLOCKS_PATH. But deleting the latter fixed it.

fventuri commented 3 years ago

I figured out where that GNU Radio version: v3.8.0.0-843-g6d6c9a2 comes from; looking through the code (&lt;GR-root&gt;/cmake/Modules/GrVersion.cmake), I found out apparently there are two version numbers in GNU Radio: one is called VERSION and comes from the output of the command git describe (which here returns v3.8.0.0-843-g6d6c9a25), while the other is called LIBVER, and this one is correctly set to 3.9.0git. I am not really sure why git describe returns a 3.8.0.0 tag even from the master branch (I even did a fresh git clone to a new directory to make sure, and the results was the same); what does git describe return for you? I am wondering if we are working on slightly different branches.

As per building log4cpp, the msbuild command you gave me worked without a problem (I just had to tell it to use a target of 142), but then I realized the log4cppLIB.vcxproj file works only for 32bit builds (Win32), while I was trying to build a 64bit of GNU Radio (x64); so my next question to you is if your build of GNU Radio is 32 bit or 64 bit, and, in case you built GNU Radio as a 64 bit program, if you manually changed the file log4cppLIB.vcxproj (and possibly other files) in order to be able to build log4cpp as a 64bit library (and I also imagine you may have had to modify other VC project files in a similar fashion).

Thanks again for all your help, Franco

gvanem commented 3 years ago

what does git describe return for you?

v3.8.0.0-844-gef9aab471

in case you built GNU Radio as a 64 bit program,

No, I have never tried that. Build most of my things using 32-bit. Looking at log4cppLIB.vcxproj, it does not contain any x64 or Win64 entries. So I fail to see how to use that for x64.

and I also imagine you may have had to modify other VC project files in a similar fashion).

Since I feel VC project files are more obfuscated than CMake, I seldom do that. Not in relation with GnuRadio anyway. I rather create a GNU-makefile for it. Or use my simple Makefile generator as a starting point.