From 9d3c8c0e6e1a7ba43bf3dc19350d1dca68b657a3 Mon Sep 17 00:00:00 2001 From: Chris Xiong Date: Sun, 10 Feb 2019 11:16:07 +0800 Subject: Initial commit. --- blog/post/2016-09-24.html | 230 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 230 insertions(+) create mode 100644 blog/post/2016-09-24.html (limited to 'blog/post/2016-09-24.html') diff --git a/blog/post/2016-09-24.html b/blog/post/2016-09-24.html new file mode 100644 index 0000000..0de4d43 --- /dev/null +++ b/blog/post/2016-09-24.html @@ -0,0 +1,230 @@ + + + + +Chrisoft::Blog + + + + + + + + + + + + + + + + + + + + +
+ +
+
+

2-in-1

+
2016-09-24
#devel #qmidiplayer #c++ #qt
+
+
+

+The visualization plugin for QMidiPlayer in Linux has suffered from a dbus-related bug for a long time: +after you have opened the visualization window, close it and try to bring it up again, it will either +result in several lines of dbus warning which suggests there's a bug in the program (on Debian sid), +or simply a crash (on Arch Linux). +

+

+Well, I have to admit the design of QMidiPlayer's visualization architecture is pretty weird: +the visualization plugin spawns its own thread and do almost everything in it. After doing some +research on the Internet, I realized that everyone suggests that Qt and SDL shouldn't be +used together, "use QtOpenGL instead". However I thought that will hang the main UI thread and +I just don't believe in the myth. +

+

+So I started my investigation in early May. I even opened an related issue on github. Unfortunately nobody +offered help. So I had to solve the issue myself. First I had a look into the dbus warnings: +

process <PID>: arguments to dbus_connection_unref() were incorrect, assertion "connection->generation == _dbus_current_generation" failed in file ../../dbus/dbus-connection.c line 2822.
+This is normally a bug in some application using the D-Bus library.
+
+

+

+Qt definitely uses dbus. After spitting these into stderr, QMidiPlayer crashes instantly in the +QDBusConnection thread. Googling the warning turned out nothing. Then I came across with this blog post +from a KDE developer:
+https://blogs.kde.org/2009/03/26/how-crash-almost-every-qtkde-application-and-how-fix-it-0 +

+

+Unfortunately, after applying the "fix", the bug didn't change even a little bit. So I had to move on. +

+

UPD 2016-10-28

+

+After several months' idleness of the investigation due to the lack of idea, I suddenly decided to have +a look at all dbus calls when QMidiPlayer crashes. Then I found the following dbus call: +

path=/org/freedesktop/ScreenSaver; interface=org.freedesktop.ScreenSaver; method=Inhibit;
+string "My SDL application"
+string "Playing a game"
+
+

+

+Apparently SDL is also using dbus to do some dirty work -- disabling the screen saver! So I appended +SDL_EnableScreenSaver in SMELT's init function. Unfortunately, nothing happened again. However I've +guessed out the cause to the problem: both Qt and SDL try to initialize a dbus connection in one +process, which is not allowed. So I have to get rid of either one of them. +

+

+Therefore I began to port the SMELT engine to GLFW. After two days of work, the port was finished and it worked +like a charm -- I have solved the problem! +

+

BUT THAT'S NOT THE END OF THE STORY.

+

+Driven by the unstoppable merriness after fixing a long-existed bug, I started to build GLFW version of +SMELT for Windows. The process was painful but finally I managed to do it successfully. After that +it's time to compile the visualization library. A beautiful DLL file, sized 1096192 bytes, was produced. +This build is almost 4x smaller than the previous failed mingw build and I regarded this as a omen of +fortune. +

+

+I put the DLL file into the plugin folder of QMidiPlayer and launched the application. No errors occured +as the mingw build once caused and the plugin showed up correctly in the plugin manager. I was so excited +that I turned on the plugin immediately and I couldn't wait to announce the result to my friends. However +when I hit the visualization I was greeted by a déjà vu scene. +

+ +

+And this nasty little dialog from the Windows 2000 era. +

+ +

+So another tale of a battle between a fierce bug and me is due to happen. Stay tuned and watch the fight! +

+[1] +

UPD@2016-12-28

+

+So the bug has been (mostly) fixed by the following two commits!
+b79c4b7e3cab3711e87ba9e28fa8423a84ea7efa@QMidiPlayer
+b13f72857af93489f535b84d62882f681dc84a73@SMELT
+

+

+Basically the most tough part to debug is caused by the stupidest typo... +

@@ -62,7 +62,7 @@ bool SMELT_IMPL::smInit()
+  		else if(i==0x80000004)
+  		memcpy(cpuName+32, CPUInfo, sizeof(CPUInfo));
+  	}
+ -	while(*cpuName=' ')++cpuName;
+ +	while(*cpuName==' ')++cpuName;
+  	smLog("%s:" SLINE ": CPU: %s\n", SYS_SDL_SRCFN,cpuName);
+  	free(loced);
+
+

+

+This naïve mistake screwed up the memory and this should be the cause that made the debugger report different stack traces in different build modes... +(that reminds me of the experience of screwing up the call stack, in which the backtrace was filled up by "0x0000000000000000 in ??()"...) +

+

+After having fixed this, it was much easier to debug the application. Soon afterwards the first working visualization plugin for QMP on Windows +came out. +

+

+Finally I have to make more complaints about the develop environment for a cross-platform C++ application developer in Microsoft Windows. +It's bloated, complicated and confusing. I wonder whether Microsoft is deliberately making it difficult in order to force more developers +to migrate to C#/.Net. What a big ambition Microsoft is bearing! +

+
+


+
[1]: + Current status of the bug in Windows:
+ Release build QMidiPlayer+Release build plugin=crash at somewhere in visualization.dll.
+ Release build QMidiPlayer+Debug build plugin=crash at somewhere in Qt5Core.dll.
+ Debug build QMidiPlayer+Debug build plugin=crash instantly on launch at plugin initialization.
+I have totally no idea about what to do next. +
+
+ +
+
+
+ \ No newline at end of file -- cgit v1.2.3