C ++控制台应用程序未返回

时间:2016-04-20 17:29:18

标签: c++ multithreading

我正在从命令行运行C ++控制台应用程序。应用程序使用ODBC从数据库系统查询数据,并将数据转储到文本文件中。偶尔,特别是在同时运行少量应用程序时,应用程序不会返回,让命令提示符等待。我甚至无法使用ctrl-C来阻止它。我必须使用任务管理器或ProcMon的End-Task。我在代码的每一步使用fprintf并写入一个单独的日志文件,我看到应用程序到达终点并据称称为return 0。当它没有挂起时,应用程序大约需要40秒来查询和转储数据。当应用程序挂起时,我看到日志文件和数据转储文件按预期生成。 我使用ProcMon,我发现线程正在等待自己。我收到这条消息:

  

odbcsql.exe的一个或多个线程处于等待状态。

这是我通过ProcMon找到的堆栈跟踪:

  • 的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
  • UMEngx86.dll!_RegQueryValueExW@24+0x1ba4
  • UMEngx86.dll!_RegQueryValueExW@24+0x18b2
  • UMEngx86.dll!_RegQueryValueExW@24+0x17f4
  • NTDLL.DLL!RtlInitializeCriticalSection + 0x10e
  • NTDLL.DLL!RtlInitializeCriticalSection +均为0x88
  • NTDLL.DLL!RtlReportSilentProcessExit +量0x108
  • NTDLL.DLL!RtlExitUserProcess + 0×81
  • odbcsql.exe + 0x2f0c
  • odbcsql.exe + 0x3185
  • NTDLL.DLL!RtlInitializeExceptionChain +值为0x8F
  • NTDLL.DLL!RtlInitializeExceptionChain + 0x5a

有任何想法或建议吗?

谢谢!

1 个答案:

答案 0 :(得分:1)

我解决了我的问题。

挂起是由ODBC调用SQLFreeHandle(SQL_HANDLE_DBC, hDbc);

引起的

这是我原始代码中包含的问题:

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);

由于我正在使用SQLDisconnect(hDbc);断开hDbc,因此对SQLFreeHandle(SQL_HANDLE_DBC, hDbc);的调用导致应用程序挂起。代码执行继续并完成,但进程挂起等待状态。

删除SQLFreeHandle(SQL_HANDLE_DBC, hDbc);后,该过程不再挂起。