|
|
<!DOCTYPE html><html><head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="theme-color" content="#000000">
<title>Chrisoft::Blog(r#"2-in-1")</title>
<meta name="description" content="«2-in-1» de spelunca ursae">
<meta name="author" content="Chris Xiong">
<script type="text/javascript" src="/panel.js"></script>
<script type="text/javascript" src="/themer.js"></script>
<script type="text/javascript" src="/blog/footnoter.js"></script>
<script type="text/javascript" src="/blog/aes-js.js"></script>
<script type="text/javascript" src="/blog/scrypt.js"></script>
<script type="text/javascript" src="/blog/sha256.js"></script>
<script type="text/javascript" src="/blog/decryptor.js"></script>
<link rel="stylesheet" type="text/css" href="/common.css">
<link rel="stylesheet" type="text/css" href="/panel.css">
<link rel="stylesheet" type="text/css" href="/theme0a.css" id="theme0a">
<link rel="stylesheet" type="text/css" href="/theme0b.css" id="theme0b">
<link rel="stylesheet" type="text/css" href="/theme1a.css" id="theme1a">
<link rel="stylesheet" type="text/css" href="/theme1b.css" id="theme1b">
<link rel="stylesheet" type="text/css" href="/theme2a.css" id="theme2a">
<link rel="stylesheet" type="text/css" href="/theme2b.css" id="theme2b">
<link rel="stylesheet" type="text/css" href="/theme3a.css" id="theme3a">
<link rel="stylesheet" type="text/css" href="/theme3b.css" id="theme3b">
<link rel="stylesheet" type="text/css" href="/blog/blogext.css">
<script>
function ol()
{
window.onresize=function()
{
if(window.innerWidth<768)
setupevents();
else unsetevents();
}
window.onresize();
loadTheme();
_decryptonload();
}
</script>
</head>
<body onload="ol()" style="overflow-x:hidden;">
<div id="panel" class="TText">
<ul id="panellist">
<li><a href="/"><h1>Chrisoft</h1></a></li>
<li><a href="/blog"><h2>Blog</h2></a></li>
<li><a href="#"><h3 id="title">2-in-1</h3></a></li>
<li><span>Tags</span>
<ul id="tagslist">
<li><a href="/blog/list/devel/">devel</a></li><li><a href="/blog/list/qmidiplayer/">qmidiplayer</a></li><li><a href="/blog/list/c++/">c++</a></li><li><a href="/blog/list/qt/">qt</a></li></ul>
</li>
<li id="tocouter">
<span>Table of Contents</span>
<ul id="tocroot">
<li><a class="toctarg" href="#tocanch0">UPD 2016-10-28</a></li><li><ul class="tocnode"><li><a class="toctarg" href="#tocanch1">BUT THAT'S NOT THE END OF THE STORY.</a></li></ul></li><li><a class="toctarg" href="#tocanch2">UPD@2016-12-28</a></li></ul>
</li>
<li style="margin-left:-0.5em"><a id="prevp" href="2016-06-21.html">Prev post</a></li>
<li style="margin-left:-0.5em"><a id="nextp" href="2017-01-09.html">Next post</a></li>
</ul>
</div>
<div id="content">
<h2 id="titleh" class="TText" style="font-wight:normal;">2-in-1</h2>
<div id="datetags" class="TText" style="margin-bottom:1em;">2016-09-24<br>#devel #qmidiplayer #c++ #qt</div>
<hr><div id="article" class="TText">
<article>
<p>
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).
</p>
<p>
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 <i>shouldn't</i> 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.
</p>
<p>
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:
</p><pre style="white-space: pre-wrap;">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.
</pre>
<p></p>
<p>
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:<br>
<a href="https://blogs.kde.org/2009/03/26/how-crash-almost-every-qtkde-application-and-how-fix-it-0">https://blogs.kde.org/2009/03/26/how-crash-almost-every-qtkde-application-and-how-fix-it-0</a>
</p>
<p>
Unfortunately, after applying the "fix", the bug didn't change even a little bit. So I had to move on.
</p>
<h3 id="tocanch0" class="tvis">UPD 2016-10-28</h3>
<p>
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:
</p><pre style="white-space: pre-wrap;">path=/org/freedesktop/ScreenSaver; interface=org.freedesktop.ScreenSaver; method=Inhibit;
string "My SDL application"
string "Playing a game"
</pre>
<p></p>
<p>
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: <b>both Qt and SDL try to initialize a dbus connection in <i>one</i>
process, which is not allowed. So I have to get rid of either one of them.</b>
</p>
<p>
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!
</p>
<h4 id="tocanch1" class="tvis">BUT THAT'S NOT THE END OF THE STORY.</h4>
<p>
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.
</p>
<p>
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.
</p>
<img src="//filestorage.chrisoft.org/blog/img/qmpcrash.png" alt="" width="70%" decoding="async">
<p>
And this nasty little dialog from the Windows 2000 era.
</p>
<img src="//filestorage.chrisoft.org/blog/img/couldntbewritten.png" alt="" width="40%" decoding="async">
<p>
So another tale of a battle between a fierce bug and me is due to happen. <s>Stay tuned and watch the fight!</s>
</p>
<a id="n1" href="#note1" class="note">[1]</a>
<h3 id="tocanch2" class="tvis">UPD@2016-12-28</h3>
<p>
So the bug has been (mostly) fixed by the following two commits!<br>
<a href="https://github.com/chirs241097/QMidiPlayer/commit/b79c4b7e3cab3711e87ba9e28fa8423a84ea7efa">b79c4b7e3cab3711e87ba9e28fa8423a84ea7efa@QMidiPlayer</a><br>
<a href="https://github.com/BearKidsTeam/SMELT/commit/b13f72857af93489f535b84d62882f681dc84a73">b13f72857af93489f535b84d62882f681dc84a73@SMELT</a><br>
</p>
<p>
Basically the most tough part to debug is caused by the stupidest typo...
</p><pre style="padding-left:20px;border:1px white solid;">@@ -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);
</pre>
<p></p>
<p>
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 ??()"...)
</p>
<p>
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.
</p>
<p>
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!
</p>
<article>
</article></article></div><br><hr>
<div class="TText" id="notediv" style="font-size:80%;"><span class="TText"><a id="note1" href="#n1">[1]</a>:
Current status of the bug in Windows:<br>
Release build QMidiPlayer+Release build plugin=crash at somewhere in visualization.dll.<br>
Release build QMidiPlayer+Debug build plugin=crash at somewhere in Qt5Core.dll.<br>
Debug build QMidiPlayer+Debug build plugin=crash instantly on launch at plugin initialization.<br>
I have totally no idea about what to do next.
<br></span></div>
<div id="insanch" style="height:3em;"></div>
<div id="footer" style="">
<div id="pagesw" class="TText" style="width:100%;height:0.5em;"></div>
<div style="text-align:center;" class="TText">
Proudly powered by SSBS <reduced style="font-size:70%;">(the static stupid blogging system)</reduced> 2.5
<br>
Content licensed under CC BY-SA 4.0. <span id="purgep" style="display:none;font-size:70%;">This page has passphrase(s) stored. Click <a href="javascript:_purgep()">here</a> to purge.</span>
</div>
</div>
<div id="cmdbuf" class="TText" style="transition:500ms;padding:1em;font-size:2em;color:white;position:absolute;background-color:rgba(0,0,0,0.6);left:50%;top:50%;transform:translate(-50%,-50%);pointer-events:none;opacity:0;">
</div>
</div>
<div id="decryptui" style="display:none;opacity:0;color:white;z-index:1000;position:fixed;left:0;top:0;width:100%;height:100%;background-color:rgba(0,0,0,0.4);transition:opacity 0.5s;">
<div id="decryptdlg" class="TText" style="padding:10px 20px;position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);background-color:rgba(0,0,0,0.6);">
<div id="keyhint" style="margin-bottom:8px;"></div>
<div style="margin-bottom:8px;">Key: <input id="keyinp" type="text" style="color:#fff;"></div>
<div style="height:2.25em;">
<button id="btndecrypt" onclick="decryptor(decid,document.getElementById('keyinp').value);" style="position:absolute;left:20px;">Decrypt</button>
<button onclick="hidedecryptui();" style="position:absolute;right:20px;">Cancel</button>
</div>
</div>
</div></body></html>
|