Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In GDB on MinGW, how do I make Ctrl-C stop the program?

Tags:

mingw

gdb

I'm on Windows, running GDB on an executable built under MinGW. The program has an infinite loop. I want to find it by hitting Ctrl + C. When I do, both the program and GDB exit. All the help on this subject seems to assume I'm on Linux.

like image 201
Mike Dunlavey Avatar asked Apr 02 '09 18:04

Mike Dunlavey


People also ask

How do I send Sigint in GDB?

From the (gdb) prompt, type signal SIGINT . This will send (surprize) SIGINT to the program being debugged. Alternatively, handle SIGINT nostop print pass will make GDB pass the signal straight to the inferior (being debugged) process. Ctrl-Z works in GDB: it suspends the process and gets you to that (gdb) prompt.

How do I stop a program in GDB?

To stop your program while it is running, type "(ctrl) + c" (hold down the ctrl key and press c). gdb will stop your program at whatever line it has just executed. From here you can examine variables and move through your program.

What does Ctrl C do in GDB?

Normally when you run a program through GDB you can press Ctrl+C to interrupt it, e.g. if it gets stuck in an infinite loop and you want to get a backtrace.


1 Answers

This is because GDB doesn't handle the Ctrl + C event of the GUI (non-console) program properly.

You can find the workaround in Workaround for GDB Ctrl-C Interrupt.


Update: Given that the mingw.org domain expired, here's the code rescued from the Web Archive:

If you find yourself trying to interrupt a program being debugged by GDB with Ctrl-C and failing then this little program will allow you to issue the break from another session. Just run it passing the Windows pid of the process being debugged and GDB will regain control. [To compile, use gcc -o debugbreak -mno-cygwin -mthreads debugbreak.c ]

/* BEGIN debugbreak.c */

#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0501
#endif

#if _WIN32_WINNT < 0x0501
#error Must target Windows NT 5.0.1 or later for DebugBreakProcess
#endif

#include <Windows.h>
#include <stddef.h>
#include <stdlib.h>

/* Compile with this line:

    gcc -o debugbreak -mno-cygwin -mthreads debugbreak.c

*/

static char errbuffer[256];

static const char *geterrstr(DWORD errcode)
{
    size_t skip = 0;
    DWORD chars;
    chars = FormatMessage(
        FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL, errcode, 0, errbuffer, sizeof(errbuffer)-1, 0);
    errbuffer[sizeof(errbuffer)-1] = 0;
    if (chars) {
        while (errbuffer[chars-1] == '\r' || errbuffer[chars-1] == '\n') {
            errbuffer[--chars] = 0;
        }
    }
    if (chars && errbuffer[chars-1] == '.') errbuffer[--chars] = 0;
    if (chars >= 2 && errbuffer[0] == '%' && errbuffer[1] >= '0'
        && errbuffer[1] <= '9')
    {
        skip = 2;
        while (chars > skip && errbuffer[skip] == ' ') ++skip;
        if (chars >= skip+2 && errbuffer[skip] == 'i'
            && errbuffer[skip+1] == 's')
        {
            skip += 2;
            while (chars > skip && errbuffer[skip] == ' ') ++skip;
        }
    }
    if (chars > skip && errbuffer[skip] >= 'A' && errbuffer[skip] <= 'Z') {
        errbuffer[skip] += 'a' - 'A';
    }
    return errbuffer+skip;
}

int main(int argc, char *argv[])
{
    HANDLE proc;
    unsigned proc_id = 0;
    BOOL break_result;

    if (argc != 2) {
        printf("Usage: debugbreak process_id_number\n");
        return 1;
    }
    proc_id = (unsigned) strtol(argv[1], NULL, 0);
    if (proc_id == 0) {
        printf("Invalid process id %u\n", proc_id);
        return 1;
    }
    proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)proc_id);
    if (proc == NULL) {
        DWORD lastError = GetLastError();
        printf("Failed to open process %u\n", proc_id);
        printf("Error code is %lu (%s)\n", (unsigned long)lastError,
            geterrstr(lastError));
        return 1;
    }
    break_result = DebugBreakProcess(proc);
    if (!break_result) {
        DWORD lastError = GetLastError();
        printf("Failed to debug break process %u\n", proc_id);
        printf("Error code is %lu (%s)\n", (unsigned long)lastError,
            geterrstr(lastError));
        CloseHandle(proc);
        return 1;
    }
    printf("DebugBreak sent successfully to process id %u\n", proc_id);
    CloseHandle(proc);
    return 0;
}

/* END debugbreak.c */

With thanks to Kyle McKay for posting the code to the cygwin mailing list http://cygwin.com/ml/cygwin/2006-06/msg00321.html

like image 170
kcwu Avatar answered Oct 07 '22 22:10

kcwu