2016-04-20 9 views
0

Ich verwende eine C++ - Konsolenanwendung über die Befehlszeile. Die Anwendung fragt Daten von einem Datenbanksystem mit ODBC ab und speichert die Daten in einer Textdatei. Gelegentlich und vor allem wenn einige gleichzeitig ausgeführt werden, kehrt die Anwendung nicht zurück und lässt die Eingabeaufforderung warten. Ich kann es nicht einmal mit ctrl-C stoppen. Ich muss End-Task vom Task-Manager oder ProcMon verwenden. Ich benutze fprintf bei jedem Schritt im Code und schreibe in eine separate Log-Datei, und ich sehe, dass die Anwendung das Ende erreicht und angeblich return 0 genannt. Wenn es nicht hängt, benötigt die Anwendung etwa 40 Sekunden, um die Daten abzufragen und auszugeben. Wenn die Anwendung hängt, sehe ich, dass die Protokolldatei und die Datenspeicherauszugsdateien wie erwartet generiert werden. Ich benutze ProcMon und ich sehe, dass der Thread auf sich selbst wartet. Ich bekomme diese Nachricht:C++ - Konsolenanwendung wird nicht zurückgegeben

ein oder mehrere Threads von odbcsql.exe sind im Wartestatus.

Dies ist der Stack-Trace, die ich durch ProcMon finden:

  • ntoskrnl.exe KeSynchronizeExecution + 0x2246
  • ntoskrnl.exe KeWaitForMultipleObjects + 0x135e
  • ntoskrnl.exe KeWaitForMultipleObjects + 0xdd9!
  • ntoskrnl.exe! KeWaitForSingleObject + 0x373
  • ntoskrnl.exe! KeStallWhileFrozen + 0x1977
  • ntoskrnl.exe! KeIsAttachedProcess + 0x95d
  • ntoskrnl.exe! KeWaitForMultipleObjects + 0x152f
  • ntoskrnl.exe! KeWaitForMultipleObjects + 0xdd9
  • ntoskrnl.exe! KeWaitForSingleObject + 0x373
  • ntoskrnl.exe! NtWaitForSingleObject + 0xB2
  • +
  • ntoskrnl.exe! setjmpex 0x34a3
  • wow64cpu.dll! TurboDispatchJumpAddressEnd + 0x598
  • wow64cpu.dll! TurboDispatchJumpAddressEnd + 0x3e4
  • wow64.dll! Wow64LdrpInitialize + 0x23a
  • wow64.dll! Wow64LdrpInitialize + 0x172
  • ntdll.dll! LdrInitShimEngineDynamic + 0x23d5
  • ntdll.dll! Memset + 0xdd1e
  • ntdll.dll! LdrInitializeThunk + 0xe
  • UMEngx86.dll + 0x242f
  • UMEngx86.dll + 0x1ec5
  • [email protected]+0x1ba4
  • UMEngx86.dll! _RegQ ueryValueExW @ 24 + 0x18b2
  • [email protected]+0x17f4
  • ntdll.dll! RtlInitializeCriticalSection + 0x10e
  • ntdll.dll! RtlInitializeCriticalSection + 0x88
  • ntdll.dll! RtlReportSilentProcessExit + 0x108
  • ntdll.dll! RtlExitUserProcess + 0x81
  • odbcsql.exe + 0x2f0c
  • odbcsql.exe + 0x3185
  • ntdll.dll! RtlInitializeExceptionChain + 0x8f
  • ntdll.dll! RtlInitializeExceptionChain + 0x5a

Irgendwelche Ideen oder Anregungen?

Danke!

+0

verbinden Sie alle Threads vor dem Beenden (Rückkehr von der Hauptfunktion)? –

+0

Ich verwende in meiner Anwendung nicht explizit Multi-Threading. Mein Code ist 1000 Zeilen, und das Problem scheint nicht Code-spezifisch, denn wie ich erwähnt, sehe ich, dass alle meine Code gerade gut ausgeführt wird (durch Blick auf die Protokolldatei). –

+0

Voting zu schließen, nur weil ich keinen Code gepostet habe, ist nicht fair von dir. Zumindest könntest du fragen, ob ich zuerst etwas Code posten kann (und ich erklärte warum nicht). Die Frage benötigt keinen Code. Ich frage im Grunde, warum eine C++ - Konsolenanwendung den Prozess nicht beenden würde, selbst wenn sie 0 erreicht hat. –

Antwort

1

Ich löste mein Problem.

Der Hang wurde durch den ODBC-Aufruf verursacht SQLFreeHandle(SQL_HANDLE_DBC, hDbc);

Hier ist meine Original-Code, der das Problem enthält:

if (hStmt != SQL_NULL_HSTMT) 
    SQLFreeHandle(SQL_HANDLE_STMT, hStmt); 

if (hDbc != SQL_NULL_HDBC) { 
    SQLDisconnect(hDbc); 
    SQLFreeHandle(SQL_HANDLE_DBC, hDbc); 
} 

if (hEnv != SQL_NULL_HENV) 
    SQLFreeHandle(SQL_HANDLE_ENV, hEnv); 

Da ich hdbc bin Trennen mit SQLDisconnect(hDbc); dann der Anruf an SQLFreeHandle(SQL_HANDLE_DBC, hDbc); die Anwendung verursacht hängen. Die Ausführung des Codes wird fortgesetzt und abgeschlossen, aber der Prozess hängt im Wartezustand.

Nachdem ich SQLFreeHandle(SQL_HANDLE_DBC, hDbc); entfernt habe, hängt der Prozess nicht mehr.

Verwandte Themen