Closed matthijskooijman closed 6 years ago
@matthijskooijman Thanks for the accurate report. Indeed there was an issue in the destructor. Fixed now
Hm, I wonder about your fix. You're now calling close()
passing a line of 0. AFAICS this should be a global line number, not a device line number, so this is effectively just a dummy (and potentially invalid) line number. In addition to stopping threads, the close()
method will also call DMXUSBWidget::close(), which will actually try to do things with the line. Since it mostly does internal bookkeeping, this is probably not a problem for this particular case (when we're already destructing things anyway), but future changes to DMXUSBWidget::close()
might cause problems.
Also, if this widget is not the first one (e.g. m_inputBaseLine
or m_outputBaseLine
is non-zero, I believe the subtraction in e.g. this line will overflow, and a "Trying to close an out of bounds input line !" warning will be shown).
Reading the code, I noticed another bug in there: currently EnttecDMXUSBPro::close
always closes the output thread, regardless of any remaining open lines. On my Pro Mk2, that has 2 output lines, this means that if I enable both outputs, and then uncheck one in the I/O tab of QLC, the output thread is stopped and both outputs stop working. Fixing this (by checking for any remaining open lines before stopping the thread) would also mean that the fix for the original issue to stop working (since that would then require all open lines to be properly closed with proper line numbers before the threads would be stopped), which is another indication that the fix for the original issue is not entirerly correct.
We're in the destructor, which means QLC+ is shutting down or the USB device has been unplugged. Therefore, DMXUSBWidget is destroyed as well. If it makes you feel better, close calls can be replaced with
close(m_inputBaseLine, true);
close(m_outputBaseLine, false);
As for multiple outputs open/close while running, I'll check that.
If it makes you feel better, close calls can be replaced with
At least that would prevent the warning from being shown, I guess :-)
I get a segfault when unplugging an Enttec DMX USB Pro configured for input. I'm running on git master (3973c82f60dbb2e84545bfc536db01d490387101), this issue did not occur on the latest 4.11.2 release. The bug happens both with a classic DMX USB PRO as well as with a MK2. The issue seems to be very reproducible.
There's a slight oddity in my setup (I did a make install to a non-system folder and only set up a symlink for the plugins), but I do not think this is the cause. I wanted to try the opensuse autobuilds for master, but those are down for maintanance apparently.
I'm including debug output and a backtrace below.
Plug in USB device:
Enable input in I/O tab:
Unplug USB:
It looks like m_interface got corrupted, with the vtable (_vptr) being zero. I've also seen versions of this crash where the v_ptr is not zero, and there is one extra unknown frame in the backtrace, so I suppose the vptr is invalid but not zero in those cases.
I've added some debug output:
Looking at the code, I suspect that the interface is freed (by
DMXUSBWidget::~DMXUSBWidget()
) before the input thread is stopped. It seems that the input thread is only freed / stopped byEnttecDMXUSBPro::close()
, so perhaps that does not run in the USB disconnected case?I added some debug output to
EnttecDMXUSBPro::close
andDMXUSBWidget::~DMXUSBWidget()
, which gives the below output, confirming my suspicion.If I add cleanup of the input thread to the EnttecDMXUSBPro destructor, things seem to work. I'm not quite sure this is a proper solution, though (I'm duplicating this code, so it should at least go into a method, I suppose). Perhaps it would be better to make sure close is called, I really have no clue :-)
Here's what I tried:
With that, the ouput becomes: