在MinGW上的GDB中,如何使Ctrl-C停止程序?

在MinGW上的GDB中,如何使Ctrl-C停止程序?,gdb,mingw,Gdb,Mingw,我在Windows上,在MinGW下构建的可执行文件上运行GDB。程序有一个无限循环。我想通过按Ctrl+C找到它。当我这样做时,程序和GDB都会退出。关于这个主题的所有帮助似乎都假设我在Linux上。要找到无限循环,可以尝试逐步执行,直到找到无限重复的序列 我不确定,但我认为Ctrl-C应该只停止执行,而不是gdb本身 我认为有一个“handle”命令可以用来控制中断信号的处理方式。您使用的是哪个“shell”?如果您使用MSYS“rxvt”shell,其行为与您描述的基本相同。只有在正常的W

我在Windows上,在MinGW下构建的可执行文件上运行GDB。程序有一个无限循环。我想通过按Ctrl+C找到它。当我这样做时,程序和GDB都会退出。关于这个主题的所有帮助似乎都假设我在Linux上。

要找到无限循环,可以尝试逐步执行,直到找到无限重复的序列

我不确定,但我认为Ctrl-C应该只停止执行,而不是gdb本身


我认为有一个“handle”命令可以用来控制中断信号的处理方式。

您使用的是哪个“shell”?如果您使用MSYS“rxvt”shell,其行为与您描述的基本相同。只有在正常的Windows命令提示符下运行时,Ctrl-C才起作用。

这是因为GDB不能正确处理GUI(非控制台)程序的Ctrl+C事件

您可以在中找到解决方法


更新:鉴于mingw.org域已过期,以下是从Web存档中解救的代码:

如果您发现自己试图用Ctrl-C中断GDB调试的程序,但失败了,那么这个小程序将允许您从另一个会话发出中断。只要通过调试进程的Windows pid运行它,GDB就会重新获得控制权。[要编译,请使用
gcc-o debugbreak-mno cygwin-mthreads debugbreak.c
]

/*开始调试break.c*/
#ifndef\u WIN32\u WINNT
#定义_WIN32_WINNT 0x0501
#恩迪夫
#如果_WIN32_WINNT<0x0501
#错误必须以Windows NT 5.0.1或更高版本为目标,才能执行DebugBreakProcess
#恩迪夫
#包括
#包括
#包括
/*用这一行编译:
gcc-o debugbreak-mno cygwin-mthreads debugbreak.c
*/
静态字符缓冲区[256];
静态常量char*geterrstr(DWORD errcode)
{
大小\u t skip=0;
德沃德·查尔斯;
chars=格式化消息(
格式化来自系统的消息,格式化消息忽略插入,
NULL,errcode,0,errbuffer,sizeof(errbuffer)-1,0);
errbuffer[sizeof(errbuffer)-1]=0;
如果(字符){
而(errbuffer[chars-1]='\r'| | errbuffer[chars-1]=='\n'){
errbuffer[--chars]=0;
}
}
如果(chars&&errbuffer[chars-1]=='.')errbuffer[--chars]=0;
如果(字符>=2&&errbuffer[0]='%'&&errbuffer[1]>='0'
&&errbuffer[1]跳过&&errbuffer[skip]=''++跳过;
如果(字符>=skip+2&&errbuffer[skip]==“i”
&&errbuffer[skip+1]=='s')
{
跳过+=2;
while(chars>skip&&errbuffer[skip]='')+跳过;
}
}

如果(chars>skip&&errbuffer[skip]>='A'&&errbuffer[skip]我刚刚遇到了同样的问题

wiki的解决方法是使用调试进程的pid运行
debugbreak
,但是
ps
不显示此pid,只显示gdb的pid。也许还有其他方法可以获得它

但是有一个更简单的解决方法。只需正常启动程序(不在gdb中),从
ps
检查pid,然后用这个pid作为第二个参数启动gdb。
连接gdb后,进程停止,我可以打印回溯。

这里有一个每次都有效的解决方案:

当GDB启动时,使用此正则表达式捕获低级进程id:

"\[New Thread (\d+)\."
然后使用:

hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, PID);
DebugBreakProcess(hProcess);
CloseHandle(hProcess);
请查看以下GDB初始化脚本,它需要在Windows 7及更高版本上与MinGW一起使用:

# =====================================
#  GDB preload initialization commands
# =====================================

# Set Unicode Charset
#set target-charset UCS-2
#set host-charset UCS-2
#set charset UCS-2
#set target-wide-charset UCS-2

# Set UTF-8 Charset
set target-charset UTF-8
set host-charset UTF-8
set charset UTF-8
set target-wide-charset UTF-8

# Request async target mode
set target-async 1

# Do not complain about pending breakpoints
set breakpoint pending on

# Enable All-Stop for all Threads
set non-stop off

# Do not ask for confirmations
set confirm off

# Do not create new console for output/logging
set new-console off

# Turn-off paggination to allow integration with IDE
set pagination off

# Call Stack files (and anywhere else) should be absolute path
set filename-display absolute

# Enable Pretty Print in GDB Panel
set print pretty on

# Enable notification of completion for asynchronous execution commands.
set exec-done-display on

# Show Addresses in objects, required for integration with IDE
set print address on

# Enable Pretty Print for Arrays
set print array on

# Flatten objects, required for integration with IDE
set print object off

# Include static members, required for integration with IDE
set print static-members on

# Show demangled vtable, required for integration with IDE
set print vtbl off
set print demangle on
set demangle-style gnu-v3

# Print full eight-bit characters, required for integration with IDE
set print sevenbit-strings off

# Set path for obj files
path $(TARGET_ROOT)/obj

# Load gdb scripts for STL (string, vector, map, etc.)
source $(PATH_SDK_DEBUGGER)/stl-views-1.0.3.gdb

# List of source code files
dir $(PATH_SDK_COMMON)
dir $(PATH_SDK_FRAMEWORKS)
dir $(PATH_SDK_INCLUDES)
dir $(PROJECT_PATHS.NATIVE_COMMON)

# Load the binary
file $(TARGET_OUTPUT)

同样,在MSYS/Cygwin中使用本机MinGW工具链构建的GDB时会发生这种情况。使用winpty启动GDB非常有吸引力,因为它是专门为此设计的工具。如果从那时开始安装最新的MinGW-x64,Ctrl-C也可以使用
cdb.exe

c:\test>gdb a.exe
GNU gdb (GDB) 7.11.1
. . .
Reading symbols from a.exe...done.
(gdb) r
Starting program: c:\test\a.exe
<Ctrl>-<C>
Thread 5 received signal SIGINT, Interrupt.
[Switching to Thread 17312.0x5614]
0x00007ff97e75d7e3 in TlsGetValue () from C:\WINDOWS\System32\KernelBase.dll
(gdb)

我也遇到了同样的问题。解决这个问题的方法是将gdb与cmd.exe一起使用,并在gdb中设置以下选项

set new-console on

现在我可以使用Ctrl+c来中断gui和控制台程序。

我知道。我希望不必这样做。这两方面你都是对的,但在Windows DOS环境下似乎不起作用。这是有用的信息。我在Windows命令提示符下,它似乎不起作用,但我会再试一次。你也可以尝试“Console2”。这应该与Windows命令提示符相近,但它要漂亮得多。我一直使用gdb,从来没有出现过任何问题。很遗憾,你只能使用变通方法调试Windows程序。至于我,我正在调试Android程序:(切换到合适的控制台,如
cmd.exe
确实有帮助:我按Ctrl+C,GDB的行为与Linux上的一样。因此,链接到此处的解决方法没有那么有用。在我的情况下,在Windows 10下使用mingw GDB测试一个程序,从powershell切换到cmd.exe没有帮助。建议的解决方法确实有帮助。谢谢。有些建议。)很久以前我碰到过这样一个问题:点击^C,调试器停止,但它停止在与主程序不同的线程中。如果我执行info threads,它会告诉主程序的线程号。然后我切换到该线程,我可以执行
bt
来显示堆栈。我想这对于真正了解GDB的人来说是显而易见的。
(gdb) handle SIGINT
SIGINT is used by the debugger.
Are you sure you want to change it? (y or n) y
Signal        Stop      Print   Pass to program Description
SIGINT        Yes       Yes     No              Interrupt
(gdb)
set new-console on