【问题标题】:How to see real call stack in WinDbg when we break with CTRL + Break当我们用 CTRL + Break 中断时,如何在 WinDbg 中查看真正的调用堆栈
【发布时间】:2017-11-06 13:09:11
【问题描述】:

当我们有一个常规断点时,调试器会在那里中断,我们会看到调用堆栈。但是如果我们使用 CTRL + Break 来中断执行呢?我希望当前正在运行的线程会破坏它原来的位置,但我看到的通常是以下内容:

 # ChildEBP RetAddr  
00 02b7fdc4 7762f216 ntdll!DbgBreakPoint
01 02b7fdf4 76c0336a ntdll!DbgUiRemoteBreakin+0x3c
02 02b7fe00 775c9902 kernel32!BaseThreadInitThunk+0xe
03 02b7fe40 775c98d5 ntdll!__RtlUserThreadStart+0x70
04 02b7fe58 00000000 ntdll!_RtlUserThreadStart+0x1b
*** WARNING: Unable to verify checksum for ThreadDemo.exe

但是我怎样才能得到被中断的当前线程的实际代码呢?

我正在运行一个长循环,如下所示,这需要一些时间,我希望它会在那里中断。

void Bank::Deposit(void* param)
{
    Bank * bank = (Bank *)param;

    char *who = (char*) bank->bankName;

    int i;
    printf("%s: begin deposite\n", who);
    for (i = 0; i < 1000000000; i++) {
        bank->balance = bank->balance + 1;
    }
    printf("%s: done\n", who);

    return;
}

在这种情况下,当它中断时,另一个线程确实会在此函数中中断,但这是一个简单的演示。当我有很多线程时,如何在真实的 Windows 应用程序中知道应用程序真正停止的位置(以及它在做什么)?

【问题讨论】:

  • 正如您所发现的,从调试器侵入进程会产生一个单独的线程来完成中断。要查看 所有 线程的堆栈跟踪,请使用 ~*kv。当您看到正在运行您要调查的代码的线程 id 时,使用~0s,假设 0 是线程 id,将其设置为当前线程。

标签: c++ multithreading debugging windows-7 windbg


【解决方案1】:

当您按下 ctrl-c 时,没有“当前正在运行的线程”。零个、一个或多个线程可能正在运行,因此调试器甚至不会尝试找出“哪个”要中断——而是在自己的线程中中断。仅仅因为您有一个当时可能正在运行的线程(但不一定如此)并不会改变这一点。

但你可以得到你想要的。当您按 ctrl-c 时,它会中断调试器线程并停止所有其他线程。您可以通过键入以下内容列出所有线程及其调用堆栈:

~*k

您也可以通过键入以下内容切换到另一个线程:

~Ns

其中 N 是要切换到的线程的 ID。

将“当前线程”设置为所需的线程后,您可以键入k 以列出其调用堆栈和其他线程特定命令。

编辑:

请参阅 this 以获取详细的 windbg 线程特定命令列表

【讨论】:

    【解决方案2】:

    当您按下 Ctrl+CCtrl+Break 时,调试器会处理该键盘事件.这意味着当时至少有一个调试器线程正在运行,而不是您的。找出之前运行的线程并不容易。

    调试器将在调用堆栈上使用int 3 指令将新线程注入您的应用程序。该线程不会立即运行,它首先必须由操作系统调度才能运行。这需要上下文切换。

    当到达int 3 时,进程中的所有线程都将被挂起,并且调试器会收到有关异常的通知。因此,在您按下一个键和线程实际停止之间,大约需要 15 毫秒到 30 毫秒之间的时间。

    不过,这没什么好担心的。鉴于人类的平均反应时间为 25 毫秒,数百万条 CPU 指令介于让您想要停止线程的观察和实际停止之间。

    正如 Sean Cline 在 cmets 和 Mike Vine 的回答中已经提到的那样,其他线程仍然存在。您可以使用~ 列出它们,使用~*k 显示它们的调用堆栈或使用~ 切换到特定线程s

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-01-24
      • 1970-01-01
      • 2017-01-26
      • 1970-01-01
      • 2023-04-06
      • 2018-09-02
      • 2016-04-26
      相关资源
      最近更新 更多