Ich schreibe eine kleine Hobby-Anwendung in C++ mit Qt. Die Anwendung hat einige Wörterbuch-Dateien beim Start zu lesen, die einige Zeit in Anspruch nimmt, so dass ich erstellte Klasse einen benutzerdefinierten Thread die Wörterbücher im Hintergrund zu analysieren:Seltsame Laufzeitfehler mit einer Multithread-C++ - Qt-Anwendung, die nur im VS-Debugger auftritt
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;
};
Die drei „Dictionary“ Klassen erstellt werden von mir und sie alle Erben eine gemeinsame Schnittstelle, die Q_OBJECT-Funktionalität enthält, um die Hauptklasse über den Kopf des Setup-Thread im Qt :: QueuedConnection-Modus mit Fortschrittsupdates während der Analyse zu signalisieren, so dass es eine Fortschrittsleiste anzeigen kann. Der Setup-Faden wird von den wichtigsten Klassen Konstruktor wie folgt aufgerufen:
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();
}
ich einige Probleme, mit der Anwendung abstürzt beim Beenden gestartet und ich konnte nicht sehen, was das Problem war, so habe ich versucht, es in denen laufen Visual C++ 2008 Debugger. Dann bekomme ich einen großen Absturz bei der Inbetriebnahme:
Unbehandelte Ausnahme bei 0x7568b727 in kanjiflash.exe: Microsoft C++ Ausnahme: std :: exception auf Speicherplatz 0x024ffa1c ..
Die Stack-Trace zeigt :
KernelBase.dll 7568b727()
KernelBase.dll 7568b727()[Rahmen für KernelBase.dll unrichtige und/oder fehlt, keine Symbole unten kann geladen werden]! msvcr90d.dll! _heap_alloc_dbg_impl (unsigned int nSize = 72, int nBlockUse = 1, const char * szFileName = 0x00000000, int nLine = 0, int * errno_tmp = 0x024ff9f8) Zeile 497 + 0xC Bytes C++
msvcr90d.dll! _nh_malloc_dbg_impl (nicht signiert int nGröße = 72, int nhFlag = 0, int nBlockUse = 1, const char * szFileName = 0x00000000, int nLine = 0, int * errno_tmp = 0x024ff9f8) Zeile 239 + 0x19 Byte C++ msvcr90d.dll! _nh_malloc_dbg (unsigned int nSize = 72, int nhFlag = 0, int nBlockUse = 1, const char * szFileName = 0x00000000, int nLinie = 0) Zeile 296 + 0x1d Bytes C++
msvcr90d.dll! malloc (unsigned int nSize = 1) Zeile 56 + 0x15 bytes C++
020bea68()
kanjiflash.exe! SetupThread :: run() Zeile 391 + 0x2c Bytes C++
QtCored4.dll! QThreadPrivate :: start (void * arg = 0x020bd0c8) Linie 317 C++
msvcr90d.dll! _callthreadstartex() Linie 348 + 0xf Bytes C
msvcr90d.dll! _threadstartex (void * PTD = 0x020bd8f0) Zeile 331 C
kernel32.dll! 75.593.677()
ntdll.dll! 77739d72()
ntdll.dll! 77739d45()
Die besondere Linie in SetupThread :: run() bezieht sich dies zu dem ist, wo ich versuche, parseDictionary ("...") auszuführen. Dieser Call-Stack wird von Windows7 64bit bezogen. In Windows XP 32bit hatte ich ein identisches Problem, der einzige Unterschied war, dass der Stack zum Konstruktor eines QString (const char * ch) von SetupThread :: run() ging, wo er sich beschwerte und den * ch-Puffer als ein paar zeigte Zeichen von Müll.
Jetzt ist das seltsame Ding, das nur innerhalb des Debuggers geschieht. Sowohl die Debug- als auch die Release-Konfiguration funktionieren außerhalb des Debuggers.Während ich mit der Anwendung herumfummelte, fand ich den Fehler, der dazu führte, dass ich den Debugger überhaupt benutzte, aber ich frage mich, was wirklich passiert und was ich tun werde, wenn ich den Debugger eines Tages benutzen muss. Da ich mich mit Multithread-Programmierung nicht auskenne, bin ich mir nicht sicher, ob es überhaupt möglich ist, sie in einem Debugger sinnvoll auszuführen, oder ob ich etwas falsch mache, zum Beispiel Zeiger auf die Hauptklasse im Worker-Thread zu bearbeiten (Zugriffsverletzung?). Jeder Einblick sehr geschätzt.
schwer zu sagen, ohne den Code zu sehen, um den Thread zu stoppen/zu beenden, aber angenommen, dass Ihr MainForm-Objekt gelöscht wird, während der Thread noch läuft, sind Sie garantiert in Schwierigkeiten. Es scheint auch, dass die exe funktioniert, wenn kein Debugger angeschlossen ist, während sie sich tatsächlich genau gleich verhält, aber das Problem nicht angezeigt wird, weil bestimmte Debugging-Funktionen nur unter dem Debugger aktiviert sind. – stijn
Der Absturz erwähnt eine std :: exception können Sie Ihren Haupt-und Ihren Thread umgeben: mit einem Versuch catch laufen und sehen, von wo die Ausnahme ausgelöst wird? –
@ David: Ich tat, wie Sie vorgeschlagen, aber meine catch-Anweisungen scheinen nicht ausgeführt werden, auch mit catch (...), und VS beschwert sich über "unbehandelte Ausnahme". Ein anderes Geheimnis. – neuviemeporte