I'm writing a little hobby application in C++ using Qt. The application has to read some dictionary files at startup which takes some time, so I created a custom thread class to parse the dictionaries in the background:
class SetupThread : public QThread
{
Q_OBJECT
public:
SetupThread(QObject *p_parent);
void setDictOutputs(WordDictionary *word, KanjiDictionary *kanji, RadicalDictionary *rad);
void run()
{
emit message("Parsing JMdict dictionary...");
m_wordDict->parseDictionary("dictionaries/JMdict_e.xml");
emit message("Parsing KANJIDIC dictionary...");
m_kanjiDict->parseDictionary("dictionaries/kanjidic2.xml");
emit message("Parsing RADKFILEX dictionary...");
m_radDict->parseDictionary("dictionaries/radkfilex.utf8");
}
signals:
void message(const QString &p_msg);
private:
WordDictionary *m_wordDict;
KanjiDictionary *m_kanjiDict;
RadicalDictionary *m_radDict;
};
The three "Dictionary" classes are created by me and they all inherit a common interface, which includes Q_OBJECT functionality to signal the main class over the head of the setup thread in Qt::QueuedConnection mode with progress updates while parsing, so it can display a progress bar. The setup thread is invoked from the main classes' constructor like this:
MainForm::MainForm(QWidget *parent, Qt::WFlags flags)
{
/* ... */
m_wordDict = new WordDictionary(this);
m_kanjiDict = new KanjiDictionary(this);
m_radDict = new RadicalDictionary(this);
m_setupThread = new SetupThread(this);
m_setupThread->setDictOutputs(m_wordDict, m_kanjiDict, m_radDict);
m_setupThread->start();
}
I started having some trouble with the application crashing on exit and I couldn't see what the problem was so I tried to run it in the Visual C++ 2008's debugger. Then I get a huge crash during start-up:
Unhandled exception at 0x7568b727 in kanjiflash.exe: Microsoft C++ exception: std::exception at memory location 0x024ffa1c..
The stack trace shows:
KernelBase.dll!7568b727()
[Frames below may be incorrect and/or missing, no symbols loaded for KernelBase.dll]
KernelBase.dll!7568b727()
msvcr90d.dll!_heap_alloc_dbg_impl(unsigned int nSize=72, int nBlockUse=1, const char * szFileName=0x00000000, int nLine=0, int * errno_tmp=0x024ff9f8) Line 497 + 0xc bytes C++
msvcr90d.dll!_nh_malloc_dbg_impl(unsigned int nSize=72, int nhFlag=0, int nBlockUse=1, const char * szFileName=0x00000000, int nLine=0, int * errno_tmp=0x024ff9f8) Line 239 + 0x19 bytes C++
msvcr90d.dll!_nh_malloc_dbg(unsigned int nSize=72, int nhFlag=0, int nBlockUse=1, const char * szFileName=0x00000000, int nLine=0) Line 296 + 0x1d bytes C++
msvcr90d.dll!malloc(unsigned int nSize=1) Line 56 + 0x15 bytes C++
020bea68()
kanjiflash.exe!SetupThread::run() Line 391 + 0x2c bytes C++
QtCored4.dll!QThreadPrivate::start(void * arg=0x020bd0c8) Line 317 C++
msvcr90d.dll!_callthreadstartex() Line 348 + 0xf bytes C
msvcr90d.dll!_threadstartex(void * ptd=0x020bd8f0) Line 331 C
kernel32.dll!75593677()
ntdll.dll!77739d72()
ntdll.dll!77739d45()
The particular line in SetupThread::run() this refers to is the one where I try to run parseDictionary("..."). This call stack is obtained from under Windows7 64bit. In Windows XP 32bit I had an identical problem, only difference was that the stack went to the constructor of a QString(const char *ch) from SetupThread::run(), where it complained and showed the *ch buffer to be a few characters of garbage.
Now the strange thing is this only happens inside the debugger. Both the Debug and Release configurations work fine outside the debugger. While fumbling with the application investigating this, I found and fixed the error which made me use the debugger in the first place but I'm wondering what is really happening and what will I do if I need to use the debugger some day. As I am not fully versed in multi-threaded programming, I'm not sure if it's even possible to run them in a debugger meaningfully, or perhaps I'm doing something wrong, like working on pointers of the main class in the worker thread (access violation?). Any insight greatly appreciated.