C++ 在命中断点之前将数据输入到调试器

C++ 在命中断点之前将数据输入到调试器,c++,visual-studio-2013,windbg,C++,Visual Studio 2013,Windbg,我有一个应用程序在目标机器上运行,并试图使用WinDbg从我的PC上调试它。现在,我想在命中条件断点之前向WinDbg输入一些值,并且在命中条件断点后,该值将作为参数传递给条件断点 我的最终目标是,我不希望WinDbg在遇到断点时等待输入超过一秒钟。大家都知道,WinDbg在遇到断点时会冻结所有线程,因此在继续(使用g)之后,我会遇到很多计时器超时问题 我知道我可以使用一个文件(通过放入所需的数据)并在到达断点时立即解析它。但我希望用户在断点到达之前输入所需的数据(最多5个),并在到达条件断点时

我有一个应用程序在目标机器上运行,并试图使用WinDbg从我的PC上调试它。现在,我想在命中条件断点之前向WinDbg输入一些值,并且在命中条件断点后,该值将作为参数传递给条件断点

我的最终目标是,我不希望WinDbg在遇到断点时等待输入超过一秒钟。大家都知道,WinDbg在遇到断点时会冻结所有线程,因此在继续(使用
g
)之后,我会遇到很多计时器超时问题

我知道我可以使用一个文件(通过放入所需的数据)并在到达断点时立即解析它。但我希望用户在断点到达之前输入所需的数据(最多5个),并在到达条件断点时将该数据传递给本地应用程序

我使用以下条件断点
bp FileName.cpp:341“j(1)”.echo \“断点命中,条件\”ed dwRand 12;gc';“gc'”


实际上,我希望在断点命中之前获得
dwRand
值,并且在断点命中时更新条件断点,因为
ed dwRand

WinDbg不会自行冻结线程,它会暂停线程,这是一个区别(有关详细信息,请参见
.hh freeze
)。如果所有计时器都在其他线程上,则可以恢复所有这些线程:

0:000> r $t0 = @$tid
0:000> ~*e .if (@$t0 != $tid) {~~[$tid]m} .else { .echo "current thread" }
current thread
0:000> ~
.  0  Id: 1624.f6c Suspend: 1 Teb: 7efdd000 Unfrozen
   1  Id: 1624.180c Suspend: 0 Teb: 7efda000 Unfrozen
   2  Id: 1624.864 Suspend: 0 Teb: 7efd7000 Unfrozen
   3  Id: 1624.1d4c Suspend: 0 Teb: 7efaf000 Unfrozen
   4  Id: 1624.14b0 Suspend: 0 Teb: 7efac000 Unfrozen
   5  Id: 1624.1e54 Suspend: 0 Teb: 7efa9000 Unfrozen
   6  Id: 1624.774 Suspend: 0 Teb: 7efa6000 Unfrozen
   7  Id: 1624.1810 Suspend: 0 Teb: 7efa0000 Unfrozen

这样,只有当前线程(
0
)保持挂起状态(
Suspend:1
),直到修改完内存。所有其他线程都在运行(
Suspend:0
)。

WinDbg不会自行冻结线程,它会暂停线程,这是一个区别(有关详细信息,请参阅
.hh freeze
)。如果所有计时器都在其他线程上,则可以恢复所有这些线程:

0:000> r $t0 = @$tid
0:000> ~*e .if (@$t0 != $tid) {~~[$tid]m} .else { .echo "current thread" }
current thread
0:000> ~
.  0  Id: 1624.f6c Suspend: 1 Teb: 7efdd000 Unfrozen
   1  Id: 1624.180c Suspend: 0 Teb: 7efda000 Unfrozen
   2  Id: 1624.864 Suspend: 0 Teb: 7efd7000 Unfrozen
   3  Id: 1624.1d4c Suspend: 0 Teb: 7efaf000 Unfrozen
   4  Id: 1624.14b0 Suspend: 0 Teb: 7efac000 Unfrozen
   5  Id: 1624.1e54 Suspend: 0 Teb: 7efa9000 Unfrozen
   6  Id: 1624.774 Suspend: 0 Teb: 7efa6000 Unfrozen
   7  Id: 1624.1810 Suspend: 0 Teb: 7efa0000 Unfrozen
这样,只有当前线程(
0
)保持挂起状态(
Suspend:1
),直到修改完内存。所有其他线程都在运行(
Suspend:0
)。

:\>ls-l :\>cat hitchange.cpp :\>hitchange.exe :\>cdb-c“bp hitchange!printf\”r$t0=poi(@esp+8);。printf\\\“实际兰特价值” e@[esp+8]=%08x\\n\\\”,@$t0;ed@esp+8 f001;气相色谱\“g;q”hitchange.exe :\>ls-l :\>cat hitchange.cpp :\>hitchange.exe :\>cdb-c“bp hitchange!printf\”r$t0=poi(@esp+8);。printf\\\“实际兰特价值” e@[esp+8]=%08x\\n\\\”,@$t0;ed@esp+8 f001;气相色谱\“g;q”hitchange.exe

不清楚您需要的输入是否应该来自的应用程序的用户或调试器的操作人员?@AlexanderBalabin我想从调试器的操作人员处获取。实际上,我想根据通过ed dwRand给出的局部变量dwRand的值来控制我的应用程序的输出。仍然不能100%确定我是否理解这个问题,但是如果您想在遇到断点时为dwRand输入新值,那么只需从
ed
命令中忽略该值,调试器就会提示输入该值。我不认为有什么方法可以在断点被击中之前完成。这与远程调试、VS2013和XDebug有什么关系?请删除与问题无关的标记。@Alexander Balabin是的,您是对的,我希望在命中断点之前获取值。不知何故,我使用链接
.cmdtree cmdtree.txt
成功地做到了这一点。但我仍然不相信,我希望有更好的用户界面来获取调试器操作人员的输入。不清楚您需要的输入是否应该来自调试器操作人员的应用程序用户?@AlexanderBalabin我希望从调试器操作人员处获取调试器。实际上,我想根据通过ed dwRand给出的局部变量dwRand的值来控制我的应用程序的输出。仍然不能100%确定我是否理解这个问题,但是如果您想在遇到断点时为dwRand输入新值,那么只需从
ed
命令中忽略该值,调试器就会提示输入该值。我不认为有什么方法可以在断点被击中之前完成。这与远程调试、VS2013和XDebug有什么关系?请删除与问题无关的标记。@Alexander Balabin是的,您是对的,我希望在命中断点之前获取值。不知何故,我使用链接
.cmdtree cmdtree.txt
成功地做到了这一点。但我仍然不相信,我希望有更好的用户界面来从操作调试器的人那里获取输入。我尝试了这个方法,但是这个命令花费的时间超过一秒钟,因此我无法实现我所需要的。我认为
~~[$tid]m
.if(@$td0!=$tid)
占用的时间稍多一些。我是否遗漏了其他内容?我注意到,尽管线程的挂起状态为0(Suspend:0),但线程没有运行,但仍然挂起并等待
g
继续。在我的应用程序中总共有26个线程在运行。@Panch:我认为恢复所有线程足够快,但我还没有测试性能。我将调查线程不恢复的事实。我发现,在任何情况下,当调试器侵入目标进程时,属于目标进程的线程都不会执行。只有当调试器执行进程或分离时,线程的挂起计数才会影响线程的行为。冻结状态仅在调试器执行进程时影响线程的行为。由此我了解到,挂起计数仅在调试器执行目标时生效。因此,当断点被命中时,线程不会运行,尽管其挂起计数为0。@Panch:感谢您研究详细信息。我不知道。这使得我的答案无效。我尝试了这个命令,但这个命令花费的时间超过一秒钟,因此我无法实现我所需要的。我认为
~~[$tid]m
.if(@$td0!=$tid)#include <stdio.h>
#include <stdlib.h>
void main (void) {
  for (int i =0; i< 10; i++){
    printf("%08x\n",rand());
  }
}
:\>cl /Zi /EHsc /nologo /W4 /analyze *.cpp /link /RELEASE
hitchange.cpp
00000029
00004823
000018be
00006784
00004ae1
00003d6c
00002cd6
000072ae
00006952
00005f90
0:000> cdb: Reading initial command 'bp hitchange!printf "r $t0 =poi(@esp+8);.pr
intf \"actual rand value @ [esp+8] = %08x\\n\",@$t0 ;ed @esp+8 f001;gc;";g;q'

actual rand value @ [esp+8] = 00000029
0000f001
actual rand value @ [esp+8] = 00004823
0000f001
actual rand value @ [esp+8] = 000018be
0000f001
actual rand value @ [esp+8] = 00006784
0000f001
actual rand value @ [esp+8] = 00004ae1
0000f001
actual rand value @ [esp+8] = 00003d6c
0000f001
actual rand value @ [esp+8] = 00002cd6
0000f001
actual rand value @ [esp+8] = 000072ae