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

glscopeclient hangs on Rigol MSO5000 #358

Closed
pepijndevos opened this issue Jul 18, 2020 · 17 comments
Closed

glscopeclient hangs on Rigol MSO5000 #358

pepijndevos opened this issue Jul 18, 2020 · 17 comments

Comments

@pepijndevos
Copy link
Contributor

When I configure the glscopeclient for my Rigol and press OK, it pops up a window if I want to kill the app or wait for it to respond, and then after a good few seconds the UI comes up.

It is extremely slow to load any data, showing like 3 WFMs, 0.05 WFM/s, and while the label of the sample rate matches what i see on the scope (2GSa/s, 4Mpts), the view is zoomed in to to 20.000 ns, while the scope shows 200us/div. One time I managed to zoom out, but generally the UI just hangs and the time scale vanishes completely when zooming too far.

I tried to trace the commands it sends:

$ ./src/glscopeclient/glscopeclient --debug --trace SCPISocketTransport
Connecting to SCPI oscilloscope at 169.254.67.109:5555
[SCPISocketTransport::SendCommand] Sending *IDN?
[SCPISocketTransport::ReadReply] Got RIGOL TECHNOLOGIES,MSO5074,MS5A221301338,00.01.03.00.01
[SCPISocketTransport::SendCommand] Sending SYST:OPT:STAT? RL2
[SCPISocketTransport::ReadReply] Got 0
[SCPISocketTransport::SendCommand] Sending WAV:FORM BYTE
[SCPISocketTransport::SendCommand] Sending WAV:MODE RAW
[SCPISocketTransport::SendCommand] Sending CHAN1:VERN ON
[SCPISocketTransport::SendCommand] Sending CHAN2:VERN ON
[SCPISocketTransport::SendCommand] Sending CHAN3:VERN ON
[SCPISocketTransport::SendCommand] Sending CHAN4:VERN ON
[SCPISocketTransport::SendCommand] Sending TIM:VERN ON
[SCPISocketTransport::SendCommand] Sending CHAN1:DISP ON
[SCPISocketTransport::SendCommand] Sending CHAN2:DISP ON
[SCPISocketTransport::SendCommand] Sending CHAN3:DISP ON
[SCPISocketTransport::SendCommand] Sending CHAN4:DISP ON
[SCPISocketTransport::SendCommand] Sending SING
[SCPISocketTransport::SendCommand] Sending TRIG:STAT?
[SCPISocketTransport::ReadReply] Got TD
[SCPISocketTransport::SendCommand]     Sending ACQ:MDEP?
[SCPISocketTransport::ReadReply]     Got 4.0000E+06
[SCPISocketTransport::SendCommand]     Sending WAV:SOUR CHAN1
[SCPISocketTransport::SendCommand]     Sending WAV:PRE?
[SCPISocketTransport::ReadReply]     Got 0,2,4000000,1,5.000000E-10,-1.000000E-3,0.000000,3.9962E-02,0,128
[SCPISocketTransport::SendCommand]     Sending WAV:STAR 1
[SCPISocketTransport::SendCommand]     Sending WAV:STOP 4000000
[SCPISocketTransport::SendCommand]     Sending WAV:DATA?
[SCPISocketTransport::SendCommand]     Sending WAV:SOUR CHAN2
[SCPISocketTransport::SendCommand]     Sending WAV:PRE?
[SCPISocketTransport::ReadReply]     Got 0,2,4000000,1,5.000000E-10,-1.000000E-3,0.000000,3.9832E-02,0,128
[SCPISocketTransport::SendCommand]     Sending WAV:STAR 1
[SCPISocketTransport::SendCommand]     Sending WAV:STOP 4000000
[SCPISocketTransport::SendCommand]     Sending WAV:DATA?
[SCPISocketTransport::SendCommand]     Sending WAV:SOUR CHAN3
[SCPISocketTransport::SendCommand]     Sending WAV:PRE?
[SCPISocketTransport::ReadReply]     Got 0,2,4000000,1,5.000000E-10,-1.000000E-3,0.000000,3.9620E-02,0,128
[SCPISocketTransport::SendCommand]     Sending WAV:STAR 1
[SCPISocketTransport::SendCommand]     Sending WAV:STOP 4000000
[SCPISocketTransport::SendCommand]     Sending WAV:DATA?
[SCPISocketTransport::SendCommand]     Sending WAV:SOUR CHAN4
[SCPISocketTransport::SendCommand]     Sending WAV:PRE?
[SCPISocketTransport::ReadReply]     Got 0,2,4000000,1,5.000000E-10,-1.000000E-3,0.000000,3.9927E-02,0,128
[SCPISocketTransport::SendCommand]     Sending WAV:STAR 1
[SCPISocketTransport::SendCommand]     Sending WAV:STOP 4000000
[SCPISocketTransport::SendCommand]     Sending WAV:DATA?
[SCPISocketTransport::SendCommand]     Sending SING
[SCPISocketTransport::SendCommand]     Sending CHAN1:SCALE?
[SCPISocketTransport::ReadReply]     Got 1
[SCPISocketTransport::SendCommand]     Sending CHAN1:OFFS?
[SCPISocketTransport::ReadReply]     Got 0
[SCPISocketTransport::SendCommand]     Sending TRIG:EDGE:SOUR?
[SCPISocketTransport::ReadReply]     Got CHAN4
    Trigger source: CHAN4
[SCPISocketTransport::SendCommand]     Sending CHAN2:SCALE?
[SCPISocketTransport::ReadReply]     Got 1
[SCPISocketTransport::SendCommand]     Sending CHAN2:OFFS?
[SCPISocketTransport::ReadReply]     Got 0
[SCPISocketTransport::SendCommand]     Sending CHAN3:SCALE?
[SCPISocketTransport::ReadReply]     Got 1
[SCPISocketTransport::SendCommand]     Sending CHAN3:OFFS?
[SCPISocketTransport::ReadReply]     Got 0
[SCPISocketTransport::SendCommand]     Sending CHAN4:SCALE?
[SCPISocketTransport::ReadReply]     Got 1
[SCPISocketTransport::SendCommand]     Sending CHAN4:OFFS?
[SCPISocketTransport::ReadReply]     Got 0
[SCPISocketTransport::SendCommand]     Sending TRIG:EDGE:LEV?
[SCPISocketTransport::ReadReply]     Got 1.200000E0
[SCPISocketTransport::SendCommand] Sending CHAN1:DISP?
[SCPISocketTransport::ReadReply] Got 1
[SCPISocketTransport::SendCommand] Sending CHAN2:DISP?
[SCPISocketTransport::ReadReply] Got 1
[SCPISocketTransport::SendCommand] Sending CHAN3:DISP?
[SCPISocketTransport::ReadReply] Got 1
[SCPISocketTransport::SendCommand] Sending CHAN4:DISP?
[SCPISocketTransport::ReadReply] Got 1
[SCPISocketTransport::SendCommand] Sending TRIG:STAT?
[SCPISocketTransport::ReadReply] Got STOP
[SCPISocketTransport::SendCommand]     Sending WAV:SOUR CHAN1
[SCPISocketTransport::SendCommand]     Sending WAV:PRE?
[SCPISocketTransport::ReadReply]     Got 0,2,4000000,1,5.000000E-10,-1.000000E-3,0.000000,3.9962E-02,0,128
[SCPISocketTransport::SendCommand]     Sending WAV:STAR 1
[SCPISocketTransport::SendCommand]     Sending WAV:STOP 4000000
[SCPISocketTransport::SendCommand]     Sending WAV:DATA?
[SCPISocketTransport::SendCommand]     Sending WAV:SOUR CHAN2
[SCPISocketTransport::SendCommand]     Sending WAV:PRE?
[SCPISocketTransport::ReadReply]     Got 0,2,4000000,1,5.000000E-10,-1.000000E-3,0.000000,3.9832E-02,0,128
[SCPISocketTransport::SendCommand]     Sending WAV:STAR 1
[SCPISocketTransport::SendCommand]     Sending WAV:STOP 4000000
[SCPISocketTransport::SendCommand]     Sending WAV:DATA?
[SCPISocketTransport::SendCommand]     Sending WAV:SOUR CHAN3
[SCPISocketTransport::SendCommand]     Sending WAV:PRE?
[SCPISocketTransport::ReadReply]     Got 0,2,4000000,1,5.000000E-10,-1.000000E-3,0.000000,3.9620E-02,0,128
[SCPISocketTransport::SendCommand]     Sending WAV:STAR 1
[SCPISocketTransport::SendCommand]     Sending WAV:STOP 4000000
[SCPISocketTransport::SendCommand]     Sending WAV:DATA?
[SCPISocketTransport::SendCommand]     Sending WAV:SOUR CHAN4
[SCPISocketTransport::SendCommand]     Sending WAV:PRE?
[SCPISocketTransport::ReadReply]     Got 0,2,4000000,1,5.000000E-10,-1.000000E-3,0.000000,3.9927E-02,0,128
[SCPISocketTransport::SendCommand]     Sending WAV:STAR 1
[SCPISocketTransport::SendCommand]     Sending WAV:STOP 4000000
[SCPISocketTransport::SendCommand]     Sending WAV:DATA?
[SCPISocketTransport::SendCommand]     Sending SING
[SCPISocketTransport::SendCommand] Sending TRIG:STAT?
[SCPISocketTransport::ReadReply] Got TD
[SCPISocketTransport::SendCommand]     Sending WAV:SOUR CHAN1
[SCPISocketTransport::SendCommand]     Sending WAV:PRE?
[SCPISocketTransport::ReadReply]     Got 0,2,4000000,1,5.000000E-10,-1.000000E-3,0.000000,3.9962E-02,0,128
[SCPISocketTransport::SendCommand]     Sending WAV:STAR 1
[SCPISocketTransport::SendCommand]     Sending WAV:STOP 4000000
[SCPISocketTransport::SendCommand]     Sending WAV:DATA?
Shutting down view for waveform CHAN1
    Average frame interval: 3558.728 ms (0.28 FPS, 3 frames)
    ----------------------------------------------------------
    Task              | Total (ms) | Average (ms) | Percentage
    ----------------------------------------------------------
    Render            |     6254.8 |     2084.941 | 100.0 %
    Cairo             |       54.0 |       18.000 | 0.9 %
    Texture download  |        2.9 |        0.966 | 0.0 %
    Prepare           |      390.3 |      130.093 | 6.2 %
    Build index       |        0.0 |        0.012 | 0.0 %
    Geometry download |       28.3 |        9.450 | 0.5 %
    Composite         |        1.6 |        0.517 | 0.0 %
Killed

When I clicked the cross, it again showed the "this app is not responding" dialog and I had to kill it.

As suggested on IRC, I also ran it in gdb, to see where it deadlocks the UI.

All the threads:

* 1    Thread 0x7ffff5152a00 (LWP 10242) "glscopeclient" 0x00007ffff5f16620 in __lll_lock_wait () from /usr/lib/libpthread.so.0
  2    Thread 0x7ffff4e23700 (LWP 10248) "gmain"         0x00007ffff5e3105f in poll () from /usr/lib/libc.so.6
  3    Thread 0x7fffeffff700 (LWP 10249) "gdbus"         0x00007ffff5e3105f in poll () from /usr/lib/libc.so.6
  5    Thread 0x7fffe7fff700 (LWP 10262) "ScopeThread"   0x00007ffff5f16b0c in recv () from /usr/lib/libpthread.so.0

All the stacktraces:

0x00007ffff5f16620 in __lll_lock_wait () from /usr/lib/libpthread.so.0
(gdb) bt
#0  0x00007ffff5f16620 in __lll_lock_wait () at /usr/lib/libpthread.so.0
azonenberg/scopehal-apps#1  0x00007ffff5f0ee81 in pthread_mutex_lock () at /usr/lib/libpthread.so.0
azonenberg/scopehal-apps#2  0x00007ffff63b4367 in __gthread_mutex_lock(__gthread_mutex_t*) (__mutex=0x555555b26848)
    at /usr/include/c++/10.1.0/x86_64-pc-linux-gnu/bits/gthr-default.h:749
azonenberg/scopehal-apps#3  0x00007ffff63b43b7 in __gthread_recursive_mutex_lock(__gthread_recursive_mutex_t*) (__mutex=0x555555b26848)
    at /usr/include/c++/10.1.0/x86_64-pc-linux-gnu/bits/gthr-default.h:811
azonenberg/scopehal-apps#4  0x00007ffff63b43ec in std::recursive_mutex::lock() (this=0x555555b26848) at /usr/include/c++/10.1.0/mutex:106
azonenberg/scopehal-apps#5  0x00007ffff63b4448 in std::lock_guard<std::recursive_mutex>::lock_guard(std::recursive_mutex&) (this=0x7fffffffbce8, __m=...)
    at /usr/include/c++/10.1.0/bits/std_mutex.h:159
azonenberg/scopehal-apps#6  0x00007ffff63f54df in RigolOscilloscope::Start() (this=0x555555b26800)
    at /home/pepijn/code/scopehal-apps/lib/scopehal/RigolOscilloscope.cpp:659
azonenberg/scopehal-apps#7  0x0000555555680020 in OscilloscopeWindow::ArmTrigger(bool) (this=0x555555b61550, oneshot=false)
    at /home/pepijn/code/scopehal-apps/src/glscopeclient/OscilloscopeWindow.cpp:2203
azonenberg/scopehal-apps#8  0x000055555567fe1f in OscilloscopeWindow::OnStart() (this=0x555555b61550)
    at /home/pepijn/code/scopehal-apps/src/glscopeclient/OscilloscopeWindow.cpp:2165
azonenberg/scopehal-apps#9  0x000055555569df04 in sigc::bound_mem_functor0<void, OscilloscopeWindow>::operator()() const (this=0x5555558480d8)
    at /usr/include/sigc++-2.0/sigc++/functors/mem_fun.h:1991
azonenberg/scopehal-apps#10 0x000055555569bea6 in sigc::adaptor_functor<sigc::bound_mem_functor0<void, OscilloscopeWindow> >::operator()() const
    (this=0x5555558480d0) at /usr/include/sigc++-2.0/sigc++/adaptors/adaptor_trait.h:256
azonenberg/scopehal-apps#11 0x00005555556978d4 in sigc::internal::slot_call0<sigc::bound_mem_functor0<void, OscilloscopeWindow>, void>::call_it(sigc::internal::slot_rep*) (rep=0x5555558480a0) at /usr/include/sigc++-2.0/sigc++/functors/slot.h:136
azonenberg/scopehal-apps#12 0x00007ffff75802b9 in Glib::SignalProxyNormal::slot0_void_callback(_GObject*, void*) () at /usr/lib/libglibmm-2.4.so.1
azonenberg/scopehal-apps#13 0x00007ffff6793052 in g_closure_invoke () at /usr/lib/libgobject-2.0.so.0
azonenberg/scopehal-apps#14 0x00007ffff67bb898 in  () at /usr/lib/libgobject-2.0.so.0
azonenberg/scopehal-apps#15 0x00007ffff67af41d in g_signal_emit_valist () at /usr/lib/libgobject-2.0.so.0
azonenberg/scopehal-apps#16 0x00007ffff67afba5 in g_signal_emit_by_name () at /usr/lib/libgobject-2.0.so.0
azonenberg/scopehal-apps#17 0x00007ffff67af80a in g_signal_emit_valist () at /usr/lib/libgobject-2.0.so.0
azonenberg/scopehal-apps#18 0x00007ffff67af980 in g_signal_emit () at /usr/lib/libgobject-2.0.so.0
azonenberg/scopehal-apps#19 0x00007ffff6e59eb9 in  () at /usr/lib/libgtk-3.so.0
azonenberg/scopehal-apps#20 0x00007ffff6793052 in g_closure_invoke () at /usr/lib/libgobject-2.0.so.0
azonenberg/scopehal-apps#21 0x00007ffff67bb2fc in  () at /usr/lib/libgobject-2.0.so.0
azonenberg/scopehal-apps#22 0x00007ffff67af41d in g_signal_emit_valist () at /usr/lib/libgobject-2.0.so.0
azonenberg/scopehal-apps#23 0x00007ffff67af980 in g_signal_emit () at /usr/lib/libgobject-2.0.so.0
azonenberg/scopehal-apps#24 0x00007ffff6e59a41 in  () at /usr/lib/libgtk-3.so.0
azonenberg/scopehal-apps#25 0x00007ffff6e17b3b in  () at /usr/lib/libgtk-3.so.0
azonenberg/scopehal-apps#26 0x00007ffff67af80a in g_signal_emit_valist () at /usr/lib/libgobject-2.0.so.0
azonenberg/scopehal-apps#27 0x00007ffff67af980 in g_signal_emit () at /usr/lib/libgobject-2.0.so.0
azonenberg/scopehal-apps#28 0x00007ffff6f2835d in  () at /usr/lib/libgtk-3.so.0
  
  #0  0x00007ffff5e3105f in poll () at /usr/lib/libc.so.6
azonenberg/scopehal-apps#1  0x00007ffff66f7168 in  () at /usr/lib/libglib-2.0.so.0
azonenberg/scopehal-apps#2  0x00007ffff66a8221 in g_main_context_iteration () at /usr/lib/libglib-2.0.so.0
azonenberg/scopehal-apps#3  0x00007ffff66a8272 in  () at /usr/lib/libglib-2.0.so.0
azonenberg/scopehal-apps#4  0x00007ffff66d1511 in  () at /usr/lib/libglib-2.0.so.0
azonenberg/scopehal-apps#5  0x00007ffff5f0c422 in start_thread () at /usr/lib/libpthread.so.0
azonenberg/scopehal-apps#6  0x00007ffff5e3bbf3 in clone () at /usr/lib/libc.so.6

#0  0x00007ffff5e3105f in poll () at /usr/lib/libc.so.6
azonenberg/scopehal-apps#1  0x00007ffff66f7168 in  () at /usr/lib/libglib-2.0.so.0
azonenberg/scopehal-apps#2  0x00007ffff66a7c03 in g_main_loop_run () at /usr/lib/libglib-2.0.so.0
azonenberg/scopehal-apps#3  0x00007ffff6a5f1a8 in  () at /usr/lib/libgio-2.0.so.0
azonenberg/scopehal-apps#4  0x00007ffff66d1511 in  () at /usr/lib/libglib-2.0.so.0
azonenberg/scopehal-apps#5  0x00007ffff5f0c422 in start_thread () at /usr/lib/libpthread.so.0
azonenberg/scopehal-apps#6  0x00007ffff5e3bbf3 in clone () at /usr/lib/libc.so.6

#0  0x00007ffff5f16b0c in recv () at /usr/lib/libpthread.so.0
azonenberg/scopehal-apps#1  0x00007ffff640fe43 in Socket::RecvLooped(unsigned char*, int) (this=0x555555b6b748, buf=0x7fffdc001270 "\n", len=4000001)
    at /home/pepijn/code/scopehal-apps/lib/xptools/Socket.cpp:311
azonenberg/scopehal-apps#2  0x00007ffff63a303d in SCPISocketTransport::ReadRawData(unsigned long, unsigned char*) (this=
    0x555555b6b740, len=4000001, buf=0x7fffdc001270 "\n") at /home/pepijn/code/scopehal-apps/lib/scopehal/SCPISocketTransport.cpp:135
azonenberg/scopehal-apps#3  0x00007ffff63f4d77 in RigolOscilloscope::AcquireData(bool) (this=0x555555b26800, toQueue=true)
    at /home/pepijn/code/scopehal-apps/lib/scopehal/RigolOscilloscope.cpp:599
azonenberg/scopehal-apps#4  0x00005555556f0ec7 in ScopeThread(Oscilloscope*) (scope=0x555555b26800)
    at /home/pepijn/code/scopehal-apps/src/glscopeclient/main.cpp:358
azonenberg/scopehal-apps#5  0x00005555556afd7c in std::__invoke_impl<void, void (*)(Oscilloscope*), Oscilloscope*>(std::__invoke_other, void (*&&)(Oscilloscope*), Oscilloscope*&&) (__f=@0x555555c40b40: 0x5555556f0caf <ScopeThread(Oscilloscope*)>) at /usr/include/c++/10.1.0/bits/invoke.h:60
azonenberg/scopehal-apps#6  0x00005555556afcd5 in std::__invoke<void (*)(Oscilloscope*), Oscilloscope*>(void (*&&)(Oscilloscope*), Oscilloscope*&&)
    (__fn=@0x555555c40b40: 0x5555556f0caf <ScopeThread(Oscilloscope*)>) at /usr/include/c++/10.1.0/bits/invoke.h:95
azonenberg/scopehal-apps#7  0x00005555556afc45 in std::thread::_Invoker<std::tuple<void (*)(Oscilloscope*), Oscilloscope*> >::_M_invoke<0ul, 1ul>(std::_Index_tuple<0ul, 1ul>) (this=0x555555c40b38) at /usr/include/c++/10.1.0/thread:264
azonenberg/scopehal-apps#8  0x00005555556afbfe in std::thread::_Invoker<std::tuple<void (*)(Oscilloscope*), Oscilloscope*> >::operator()()
    (this=0x555555c40b38) at /usr/include/c++/10.1.0/thread:271
azonenberg/scopehal-apps#9  0x00005555556afbe2 in std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)(Oscilloscope*), Oscilloscope*> > >::_M_run() (this=0x555555c40b30) at /usr/include/c++/10.1.0/thread:215
azonenberg/scopehal-apps#10 0x00007ffff6196b74 in std::execute_native_thread_routine(void*) (__p=0x555555c40b30)
    at /build/gcc/src/gcc/libstdc++-v3/src/c++11/thread.cc:80
azonenberg/scopehal-apps#11 0x00007ffff5f0c422 in start_thread () at /usr/lib/libpthread.so.0
azonenberg/scopehal-apps#12 0x00007ffff5e3bbf3 in clone () at /usr/lib/libc.so.6
@pepijndevos
Copy link
Contributor Author

pepijndevos commented Jul 18, 2020

It appears that this is not actually directly a scopehal problem at all. When changing the sample depth to 1K it does a little over 1 waveform per second. At 10k and 100k it becomes only marginally slower, but at 1M it becomes significantly slower and at 10M it hangs completely.

At this point no more data is sent in Wireshark, so it could potentially be a problem on the scope. Maybe it could transfer data in smaller sections?

So as discussed on IRC, the issue can be pivoted to "rigol driver is slow, can we make it faster?". Maybe the answer is just "no". I installed their own scope software, and it seems to be similarly slow and of low sample depth.

A possibly unrelated problem is that the sending of commands does not appear to happen immediately. When loading the configuration from the scope, no commands are sent until a few seconds AND after the mouse is hovered over the start button. Strange but true. Maybe there is also an unnecessary delay in sending other commands, making it slow.

@pepijndevos
Copy link
Contributor Author

After the latest caching changes I now get the following traces with 1k sample depth. It's definitely some racy mutex thing, as the may thread gets stuck on a different functioin call every time, but always with the scope thread in aquire.

(gdb) info threads
  Id   Target Id                                         Frame 
* 1    Thread 0x7ffff5150a00 (LWP 22287) "glscopeclient" 0x00007ffff5f14620 in __lll_lock_wait () from /usr/lib/libpthread.so.0
  2    Thread 0x7ffff4e21700 (LWP 22291) "gmain"         0x00007ffff5e2f05f in poll () from /usr/lib/libc.so.6
  3    Thread 0x7fffeffff700 (LWP 22292) "gdbus"         0x00007ffff5e2f05f in poll () from /usr/lib/libc.so.6
  5    Thread 0x7fffe7fff700 (LWP 22294) "ScopeThread"   0x00007ffff5f14b0c in recv () from /usr/lib/libpthread.so.0
(gdb) bt
#0  0x00007ffff5f14620 in __lll_lock_wait () at /usr/lib/libpthread.so.0
azonenberg/scopehal-apps#1  0x00007ffff5f0ce81 in pthread_mutex_lock () at /usr/lib/libpthread.so.0
azonenberg/scopehal-apps#2  0x00007ffff63b23b7 in __gthread_mutex_lock(__gthread_mutex_t*) (__mutex=0x5555559116c8)
    at /usr/include/c++/10.1.0/x86_64-pc-linux-gnu/bits/gthr-default.h:749
azonenberg/scopehal-apps#3  0x00007ffff63b2407 in __gthread_recursive_mutex_lock(__gthread_recursive_mutex_t*) (__mutex=0x5555559116c8)
    at /usr/include/c++/10.1.0/x86_64-pc-linux-gnu/bits/gthr-default.h:811
azonenberg/scopehal-apps#4  0x00007ffff63b243c in std::recursive_mutex::lock() (this=0x5555559116c8) at /usr/include/c++/10.1.0/mutex:106
azonenberg/scopehal-apps#5  0x00007ffff63b2498 in std::lock_guard<std::recursive_mutex>::lock_guard(std::recursive_mutex&)
    (this=0x7fffffffb9d8, __m=...) at /usr/include/c++/10.1.0/bits/std_mutex.h:159
azonenberg/scopehal-apps#6  0x00007ffff63f2d47 in RigolOscilloscope::GetChannelOffset(unsigned long) (this=0x555555911680, i=1)
    at /home/pepijn/code/scopehal-apps/lib/scopehal/RigolOscilloscope.cpp:524
azonenberg/scopehal-apps#7  0x00007ffff63b18ca in OscilloscopeChannel::GetOffset() (this=0x5555557a9300)
    at /home/pepijn/code/scopehal-apps/lib/scopehal/OscilloscopeChannel.cpp:93
azonenberg/scopehal-apps#8  0x00005555556dd3af in WaveformArea::YPositionToVolts(float) (this=0x555555ce5800, y=2)
    at /home/pepijn/code/scopehal-apps/src/glscopeclient/WaveformArea_rendering.cpp:644
azonenberg/scopehal-apps#9  0x00005555556e03d2 in WaveformArea::RenderGrid(Cairo::RefPtr<Cairo::Context>) (this=0x555555ce5800, cr=...)
    at /home/pepijn/code/scopehal-apps/src/glscopeclient/WaveformArea_cairo.cpp:142
azonenberg/scopehal-apps#10 0x00005555556dfb3c in WaveformArea::DoRenderCairoUnderlays(Cairo::RefPtr<Cairo::Context>)
    (this=0x555555ce5800, cr=...) at /home/pepijn/code/scopehal-apps/src/glscopeclient/WaveformArea_cairo.cpp:57
azonenberg/scopehal-apps#11 0x00005555556dca80 in WaveformArea::ComputeAndDownloadCairoUnderlays() (this=0x555555ce5800)
    at /home/pepijn/code/scopehal-apps/src/glscopeclient/WaveformArea_rendering.cpp:511
azonenberg/scopehal-apps#12 0x00005555556dbc93 in WaveformArea::on_render(Glib::RefPtr<Gdk::GLContext> const&) (this=0x555555ce5800)
    at /home/pepijn/code/scopehal-apps/src/glscopeclient/WaveformArea_rendering.cpp:277
azonenberg/scopehal-apps#13 0x00007ffff7ba6c7e in Gtk::GLArea_Class::render_callback(_GtkGLArea*, _GdkGLContext*) ()
    at /usr/lib/libgtkmm-3.0.so.1
azonenberg/scopehal-apps#14 0x00007ffff6e18ab6 in  () at /usr/lib/libgtk-3.so.0
azonenberg/scopehal-apps#15 0x00007ffff67ae80a in g_signal_emit_valist () at /usr/lib/libgobject-2.0.so.0
azonenberg/scopehal-apps#16 0x00007ffff67ae980 in g_signal_emit () at /usr/lib/libgobject-2.0.so.0
azonenberg/scopehal-apps#17 0x00007ffff6f2ba5f in  () at /usr/lib/libgtk-3.so.0
azonenberg/scopehal-apps#18 0x00007ffff7c249fb in Gtk::Widget::on_draw(Cairo::RefPtr<Cairo::Context> const&) () at /usr/lib/libgtkmm-3.0.so.1
azonenberg/scopehal-apps#19 0x00007ffff7c2fca5 in Gtk::Widget_Class::draw_callback(_GtkWidget*, _cairo*) () at /usr/lib/libgtkmm-3.0.so.1
azonenberg/scopehal-apps#20 0x00007ffff70cb30a in  () at /usr/lib/libgtk-3.so.0
azonenberg/scopehal-apps#21 0x00007ffff6e97f91 in gtk_container_propagate_draw () at /usr/lib/libgtk-3.so.0
azonenberg/scopehal-apps#22 0x00007ffff6e9809e in  () at /usr/lib/libgtk-3.so.0
azonenberg/scopehal-apps#23 0x00007ffff6e460fd in  () at /usr/lib/libgtk-3.so.0
azonenberg/scopehal-apps#24 0x00007ffff6e988dd in  () at /usr/lib/libgtk-3.so.0
azonenberg/scopehal-apps#25 0x00007ffff6ea45eb in  () at /usr/lib/libgtk-3.so.0
azonenberg/scopehal-apps#26 0x00007ffff6e465b1 in  () at /usr/lib/libgtk-3.so.0
azonenberg/scopehal-apps#27 0x00007ffff70cb30a in  () at /usr/lib/libgtk-3.so.0
azonenberg/scopehal-apps#28 0x00007ffff6e97f91 in gtk_container_propagate_draw () at /usr/lib/libgtk-3.so.0
azonenberg/scopehal-apps#29 0x00007ffff6e9809e in  () at /usr/lib/libgtk-3.so.0
azonenberg/scopehal-apps#30 0x00007ffff6e460fd in  () at /usr/lib/libgtk-3.so.0
azonenberg/scopehal-apps#31 0x00007ffff6e988dd in  () at /usr/lib/libgtk-3.so.0
azonenberg/scopehal-apps#32 0x00007ffff6ea45eb in  () at /usr/lib/libgtk-3.so.0
azonenberg/scopehal-apps#33 0x00007ffff6e465b1 in  () at /usr/lib/libgtk-3.so.0
azonenberg/scopehal-apps#34 0x00007ffff70cb30a in  () at /usr/lib/libgtk-3.so.0
azonenberg/scopehal-apps#35 0x00007ffff6e97f91 in gtk_container_propagate_draw () at /usr/lib/libgtk-3.so.0
azonenberg/scopehal-apps#36 0x00007ffff6e9809e in  () at /usr/lib/libgtk-3.so.0
azonenberg/scopehal-apps#37 0x00007ffff6f23469 in  () at /usr/lib/libgtk-3.so.0
azonenberg/scopehal-apps#38 0x00007ffff6e988dd in  () at /usr/lib/libgtk-3.so.0
azonenberg/scopehal-apps#39 0x00007ffff6ea45eb in  () at /usr/lib/libgtk-3.so.0
azonenberg/scopehal-apps#40 0x00007ffff6f1eee1 in  () at /usr/lib/libgtk-3.so.0
--Type <RET> for more, q to quit, c to continue without paging--q
Quit
(gdb) thread 2
[Switching to thread 2 (Thread 0x7ffff4e21700 (LWP 22291))]
#0  0x00007ffff5e2f05f in poll () from /usr/lib/libc.so.6
(gdb) bt
#0  0x00007ffff5e2f05f in poll () at /usr/lib/libc.so.6
azonenberg/scopehal-apps#1  0x00007ffff66f6168 in  () at /usr/lib/libglib-2.0.so.0
azonenberg/scopehal-apps#2  0x00007ffff66a7221 in g_main_context_iteration () at /usr/lib/libglib-2.0.so.0
azonenberg/scopehal-apps#3  0x00007ffff66a7272 in  () at /usr/lib/libglib-2.0.so.0
azonenberg/scopehal-apps#4  0x00007ffff66d0511 in  () at /usr/lib/libglib-2.0.so.0
azonenberg/scopehal-apps#5  0x00007ffff5f0a422 in start_thread () at /usr/lib/libpthread.so.0
azonenberg/scopehal-apps#6  0x00007ffff5e39bf3 in clone () at /usr/lib/libc.so.6
(gdb) thread 3
[Switching to thread 3 (Thread 0x7fffeffff700 (LWP 22292))]
#0  0x00007ffff5e2f05f in poll () from /usr/lib/libc.so.6
(gdb) bt
#0  0x00007ffff5e2f05f in poll () at /usr/lib/libc.so.6
azonenberg/scopehal-apps#1  0x00007ffff66f6168 in  () at /usr/lib/libglib-2.0.so.0
azonenberg/scopehal-apps#2  0x00007ffff66a6c03 in g_main_loop_run () at /usr/lib/libglib-2.0.so.0
azonenberg/scopehal-apps#3  0x00007ffff6a5e1a8 in  () at /usr/lib/libgio-2.0.so.0
azonenberg/scopehal-apps#4  0x00007ffff66d0511 in  () at /usr/lib/libglib-2.0.so.0
azonenberg/scopehal-apps#5  0x00007ffff5f0a422 in start_thread () at /usr/lib/libpthread.so.0
azonenberg/scopehal-apps#6  0x00007ffff5e39bf3 in clone () at /usr/lib/libc.so.6
(gdb) thread 5
[Switching to thread 5 (Thread 0x7fffe7fff700 (LWP 22294))]
#0  0x00007ffff5f14b0c in recv () from /usr/lib/libpthread.so.0
(gdb) bt
#0  0x00007ffff5f14b0c in recv () at /usr/lib/libpthread.so.0
azonenberg/scopehal-apps#1  0x00007ffff640ed29 in Socket::RecvLooped(unsigned char*, int)
    (this=0x555555998538, buf=0x7fffdc000c40 "\n", len=1001)
    at /home/pepijn/code/scopehal-apps/lib/xptools/Socket.cpp:311
azonenberg/scopehal-apps#2  0x00007ffff63a108d in SCPISocketTransport::ReadRawData(unsigned long, unsigned char*) (this=
    0x555555998530, len=1001, buf=0x7fffdc000c40 "\n")
    at /home/pepijn/code/scopehal-apps/lib/scopehal/SCPISocketTransport.cpp:135
azonenberg/scopehal-apps#3  0x00007ffff63f3ab0 in RigolOscilloscope::AcquireData(bool) (this=0x555555911680, toQueue=true)
    at /home/pepijn/code/scopehal-apps/lib/scopehal/RigolOscilloscope.cpp:682
azonenberg/scopehal-apps#4  0x00005555556f0ec7 in ScopeThread(Oscilloscope*) (scope=0x555555911680)
    at /home/pepijn/code/scopehal-apps/src/glscopeclient/main.cpp:358
azonenberg/scopehal-apps#5  0x00005555556afd7c in std::__invoke_impl<void, void (*)(Oscilloscope*), Oscilloscope*>(std::__invoke_other, void (*&&)(Oscilloscope*), Oscilloscope*&&) (__f=@0x555555ba98e0: 0x5555556f0caf <ScopeThread(Oscilloscope*)>)
    at /usr/include/c++/10.1.0/bits/invoke.h:60
azonenberg/scopehal-apps#6  0x00005555556afcd5 in std::__invoke<void (*)(Oscilloscope*), Oscilloscope*>(void (*&&)(Oscilloscope*), Oscilloscope*&&) (__fn=@0x555555ba98e0: 0x5555556f0caf <ScopeThread(Oscilloscope*)>) at /usr/include/c++/10.1.0/bits/invoke.h:95
azonenberg/scopehal-apps#7  0x00005555556afc45 in std::thread::_Invoker<std::tuple<void (*)(Oscilloscope*), Oscilloscope*> >::_M_invoke<0ul, 1ul>(std::_Index_tuple<0ul, 1ul>) (this=0x555555ba98d8) at /usr/include/c++/10.1.0/thread:264
azonenberg/scopehal-apps#8  0x00005555556afbfe in std::thread::_Invoker<std::tuple<void (*)(Oscilloscope*), Oscilloscope*> >::operator()()
    (this=0x555555ba98d8) at /usr/include/c++/10.1.0/thread:271
azonenberg/scopehal-apps#9  0x00005555556afbe2 in std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)(Oscilloscope*), Oscilloscope*> > >::_M_run() (this=0x555555ba98d0) at /usr/include/c++/10.1.0/thread:215
azonenberg/scopehal-apps#10 0x00007ffff6194b74 in std::execute_native_thread_routine(void*) (__p=0x555555ba98d0)
    at /build/gcc/src/gcc/libstdc++-v3/src/c++11/thread.cc:80
azonenberg/scopehal-apps#11 0x00007ffff5f0a422 in start_thread () at /usr/lib/libpthread.so.0
azonenberg/scopehal-apps#12 0x00007ffff5e39bf3 in clone () at /usr/lib/libc.so.6

@pepijndevos
Copy link
Contributor Author

This is the trace from wireshark, which includes my model scope and version. It just simply does not send any data.

*IDN?
RIGOL TECHNOLOGIES,MSO5074,MS5A221301338,00.01.03.00.01
SYST:OPT:STAT? RL2
0
WAV:FORM BYTE
WAV:MODE RAW
CHAN1:VERN ON
CHAN2:VERN ON
CHAN3:VERN ON
CHAN4:VERN ON
TIM:VERN ON
CHAN1:DISP ON
CHAN2:DISP ON
CHAN3:DISP ON
CHAN4:DISP ON
SING
TRIG:STAT?
RUN
CHAN1:SCALE?
5E-1
TRIG:STAT?
TD
ACQ:MDEP?
1.0000E+03
WAV:SOUR CHAN1
WAV:PRE?
0,2,1000,1,2.000000E-4,-1.000000E-1,0.000000,1.9963E-02,-50,128
WAV:STAR 1
WAV:STOP 1000
WAV:DATA?
#9000001000wyxvxwvtuutsussqxxvvvwvtussrwxwvvwustruxxvutusuwwvuttrwwwutswwvuutwzxuttwxwvuwxyvuxyxvux{uvyzxwvyzxv{zxxzzyxzzxxz{yxzzx}|z}.}~.}{}~|z{~z}||~~...}}.}.~~.....~~.~...............................................................................................................................................................................................................................................................................................................................................................................................................................................................................~...........~...~..~~.~~}~~~{~}}|.|{z|||z||zz|{zz|{yx{{yxyzywyywvwxxuwwuuwvuuvvusuusrutsrxywvwwuuwutruurrwyvwxvututsrwywvwutttrruxuuuusruxwvttqvxxvustuwwwuswyxutuvwxwtxyxuuyywwvyxwuvxywwyzyxy{zxz{zy{|zxz}zxy|zxz|{xz{z||{~~{}~|..~z}~}}}|.....}~..........}...........................................................................................................................
WAV:SOUR CHAN2
WAV:PRE?
0,2,1000,1,2.000000E-4,-1.000000E-1,0.000000,1.9957E-02,-50,128
WAV:STAR 1
WAV:STOP 1000
WAV:DATA?
#9000001000z...y...w...t...x...x...t...w...w...s...v...s...w...s...v...v...t...w...u...t...v...v...x...x...w...x...w...x...x...x...z...x...w...v..~z..|z..{y..{|..{|..zz..}|..~{..|}..{}..y~..{}..{~..y~..{...y...x...|...x...{...y...z...x...z...u...x...z...z...w...x...z...{...|...z...z...y...{...}...}...|...z...y...}...}...|...~...~...|.......~..........~...}.......~.......}...z...|...y...|...y...{...x...y...{...|...x...x...y...z...z...z...z...z...y...y...z...{...x...x...w...v...u.......x...w...v..~y...w..|...|y..|x.......x..}...{y..{{..yy..{{..|...y{..{}..z...w...z|..z...z...y...z...x...y...w...z...t...x...y...{...z...w...x...y...y...x...x...x...x...x...{...~...{...{...~..~~..~}..}~..|~..{...z...z...y...y...v...v...z...y...w...u...x...w...u...w...w...s...w...s...w...s...v...s...u...w...s...t...w...x...v...s...t...u...v...v...u...v...u...u...x...{..~y..~x..~{..}{..|y..{{..}{..}y..|}..{{..x...{|..{...y...{...{...x}..z...x...y...y...z...x...y...w...z...x...v...x...{...y...v...x...y...y...y...y...x...y
WAV:SOUR CHAN3
WAV:PRE?
0,2,1000,1,2.000000E-4,-1.000000E-1,0.000000,1.9984E-02,-50,128
WAV:STAR 1
WAV:STOP 1000
WAV:DATA?
#9000001000qsrqrprqrqqrrrrrsrrrrrqqsqsrrrqrqsrrrsrrsrrrtsrqssrsssqrsttssttttststttttstttustttuttvuvwtvwvvwvxwwwwyxvwwxywyyywyxyyxzzyzzzzzzz{{z|{{||||||{}}||}}}~}}~~~~......................................................................................................................................................................................................................................................................................................................................................................................................................................~..}~~~}~|}|}|}|{|}|{|{|z{z{{{{yz|yzzyzyyyyyxxyyyxwxxxwvwwwvvwvwwvvvwuvuuuvvutvutvtuuttutrtttstsssttrsstssrtrtsqsrssrsqsrsssrrqsrrrrsrrqprqrqqrrqrpqrrrrrqqrqrrrrqpqrqrqrrrqrssrrqsrrqttrrstrsqtrssssrrtsssustttssttttuuttutuuutuuvuwvwwuwvwxwxwxwxxwyyxxxyzxyyyz{z{yz{{z{zyzz{|z|{|||}|||}}}|~~}~~.~~.................................................................................................................................
WAV:SOUR CHAN4
WAV:PRE?
0,2,1000,1,2.000000E-4,-1.000000E-1,0.000000,1.9969E-02,-50,128
WAV:STAR 1
WAV:STOP 1000
WAV:DATA?
#9000001000.M...M...L...M...N...M...O..}M..zN..yP..vQ..sQ..rS..qS..oU..mU..kW..iX..gY..eZ..d[..a^..`].._`..]b..]c..Zc..Yf..Xg..Vk..Vk..Um..So..Rq..Rt..Qu..Qx..Oz..O{..N}..N...N...M...N...N...M...L...M...M...M...M...M..|O..zO..xQ..vP..tQ..rR..pS..nT..mU..jW..hX..gY..d[..d[..b]..`_..^_..^b..]d..Zf..Zf..Wh..Wi..Um..Un..Tp..Ss..Rt..Qv..Ox..Pz..N}..N...M...N...M...N...M...M...M...N...N...N...N...N..{O..zO..xP..vQ..tP..sR..pS..nT..lV..jV..iW..fX..e[..d\..a^..a_..^`..\a..\b..[d..Yg..Wj..Wk..Ul..Tn..Rp..Rr..Qt..Pv..Px..Oz..N|..N~..O...N...N...M...M...M...K...M...M...N...N..~N..|O..yP..xP..uQ..sQ..qR..qS..nT..lU..jW..iY..gZ..e[..b\..b]..`_..^a..]a..\c..Ze..Zg..Xi..Xk..Vl..To..Sq..Rq..Qs..Pv..Px..Pz..N|..N...M...N...M...M...M...M...L...M...N...M...M..}N..{O..yP..wQ..vQ..sR..qS..oS..nT..mV..iW..iY..fY..d[..d[..a]..`^.._`..]b..[c..[d..Yg..Xj..Vk..Ul..To..Sp..Rr..Rt..Qw..Ox..P{..O|..O...N...M...M...M...M...L...L...M...N...N...N..}O..{O..yO..xP..tQ..sR..rS..oT..nT..kV..kV..gX..gY..d[..c\..a^..`_.._a..]b..\d..[
SING
TRIG:STAT?
STOP
WAV:SOUR CHAN1
WAV:PRE?
0,2,1000,1,2.000000E-4,-1.000000E-1,0.000000,1.9963E-02,-50,128
WAV:STAR 1
WAV:STOP 1000
WAV:DATA?
#9000001000

@pepijndevos
Copy link
Contributor Author

pepijndevos commented Jul 21, 2020

After fixing the timeout behaviour, I got the following long trace. I can't tell any obvious reason why it'd just not return data.

glscopeclient3.txt

@pepijndevos
Copy link
Contributor Author

I have discovered that the bug can be reproduced by zooming in and out on the timescale.
Zoomed in the program runs fine (first half of the Wireshark capture), and zoomed out it stops sending data (second half of the Wireshark capture)

glscopeclient_zoom.zip

It is interesting to look at the timing of operations. The SING command takes several hundreds of ms to become responsive again, looking at the time from SING to the first reply to TRIG?.

It is hard to tell from the trace, but my impression is that when the time between the TRIG:STAT? reply and the WAV:DATA? command is short, it bugs out and sends nothing. Does anyone know the Wireshark-fu to measure latency between various commands and them working or not?

Concretely speaking, assuming we're indeed reading too fast, the question is... now what? Do we just insert a delay? Can we measure when it's actually ready? Hrmmmm

@pepijndevos
Copy link
Contributor Author

I got the following reply from Rigol, suggesting that the MODE and FORM command have to be sent every time. I asked for clarification on this point and sent them my Wireshark trace.

Following is the answer from our technical colleague for your question:

If you want to get the wave data from the screen . the command sequence is =
below:

S1. :WAV:SOUR CHAN1
S2. :WAV:MODE NORMal
S3. :WAV:FORM BYTE
S4. :WAV:DATA?

If you want to get the wave data from the memory . the command sequence is =
below:

S1. :WAV:SOUR CHAN1
S2. :WAV:MODE RAW
S3. :WAV:FORM BYTE
S4. :STOP
S5. :WAVeform:POINts 10000
S6. :WAV:DATA?

@pepijndevos
Copy link
Contributor Author

So I wanted to look at how their own software works, which appears to be running continuously. How does it synchronize? It does not. The two slow sines are in phase on the scope, and almost in antiphase on the PC, I can see why glscopeclient uses single runs.
scope

But of course the main thing I came for is the Wireshark trace of their software:
rigol_windows.zip
Unlike scopehal, it uses some VXI RCP thing that basically sends the same commands with extra steps it appears.
It's very slow and boring, but seems to work fine.

The only thing worth noting is that they don't send MODE and FORM as Rigol told me, they only do this once.

So what have we learned? Not much. Their software is slow but works.

@pepijndevos
Copy link
Contributor Author

It gets weirder! I tried the LXI transport, and the good news is that it doesn't hang or timeout, but I assure you that channel 1-3 have no signal on them.
Screenshot from 2020-07-24 17-52-26
The program does not hang or error. It just... gets the data for the wrong channel??? It randomly alternates between everything being as it should, or channel 1, 1 and 2, or 1, 2 and 3 showing channel 4 data.

So I guess while it's busy triggering and updating, it may just return stale or no data at all?

In the Wireshark trace it shows that the RPC encapsulation stops it from hanging, but does not stop it from sending empty DATA? replies. Telling from the trace when it sends wrong data is less easy, so I can't rule out that's a buffer overflow error in glscopeclient when it gets less data than expected.
glscopeclient_lxi.zip

@pepijndevos
Copy link
Contributor Author

Right, so the LXI transport will just copy less bytes when it gets a shorter reply.
https://github.com/azonenberg/scopehal/blob/c15697842071f9b77f048e30f502817d0bd4b98b/scopehal/SCPILxiTransport.cpp#L205
And the Rigol driver just assumes temp_buffer is all good and fresh.
https://github.com/azonenberg/scopehal/blob/c15697842071f9b77f048e30f502817d0bd4b98b/scopehal/RigolOscilloscope.cpp#L682
So if the scope returns no data, glscopeclient will just reuse whatever was in temp_buffer.

A hacky solution would be to zero the buffer before reading and YOLO. I think the proper solution is to change the API to return the number of bytes read, and handle it correctly in all drivers. Or turn len into a pointer type so it's updated with the actual length, much in the same way getsockopt works.

@pepijndevos
Copy link
Contributor Author

Rigol:

It should be noted that if the user is reading the memory data (raw mode), it is necessary to send the stop command to stop the oscilloscope. At the same time, it is suggested to delay 500 ms after the stop, because there is moving operation of the memory data.

Uuuuuhhhh?! So I guess you'd either use screen mode or insert a delay? Yuk.

@pepijndevos
Copy link
Contributor Author

I tested :WAVeform:MODE NORMal and it actually works significantly better. Of course the resolution is limited to 1000 points regardless of memory depth, but it never hangs and seems marginally faster. Still only 0.6 WFM/s but okay.

@azonenberg
Copy link
Collaborator

@pepijndevos @kench I've been told by several people that the hang is fixed with latest firmware from Rigol, please test and confirm.

@bvernoux
Copy link
Contributor

bvernoux commented Nov 2, 2020

I confirm with my Rigol MSO5074 with HW 01.01.00 and latest Firmware Upgrade 01.03.00.01 (Released on 12 Aug 2020) there is no freeze or crash on Rigol side
@pepijndevos I see you have Firmware 01.03.00.01 but what is your HW version ?

@azonenberg
Copy link
Collaborator

Seems like the general consensus is that it's fixed. If anybody still has problems it's likely a new bug, so open a new ticket.

@azonenberg azonenberg transferred this issue from ngscopeclient/scopehal-apps Dec 3, 2020
@azonenberg
Copy link
Collaborator

New root cause identified. Reopened and migrated to scopehal repo.

@azonenberg azonenberg reopened this Dec 3, 2020
bvernoux added a commit to bvernoux/scopehal that referenced this issue Dec 3, 2020
Fix the issue ngscopeclient#358 glscopeclient hangs on Rigol MSO5000
This fix oscilloscope single trigger synchronization with waveform data by adding "*WAI" command which "Waits for all the pending operations to complete before executing any additional commands." (it is an IEEE488.2 Common Commands)
@bvernoux
Copy link
Contributor

bvernoux commented Dec 3, 2020

Feedback are welcome here it is rock stable with Windows7 64bits build with 0.94 WFM/s
image

@azonenberg
Copy link
Collaborator

Hopefully fixed for good in 6bfbfb4.

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

No branches or pull requests

3 participants