Commit | Line | Data |
---|---|---|
3719602c PC |
1 | #ifndef _WIN32_WINNT |
2 | #define _WIN32_WINNT 0x0501 | |
3 | #endif | |
4 | ||
5 | #if _WIN32_WINNT < 0x0501 | |
6 | #error Must target Windows NT 5.0.1 or later for DebugBreakProcess | |
7 | #endif | |
8 | ||
9 | #include <Windows.h> | |
10 | ||
11 | #include <stdio.h> | |
12 | #include <stddef.h> | |
13 | #include <stdlib.h> | |
14 | ||
15 | /* Compile with this line: | |
16 | ||
17 | gcc -o debugbreak -mno-cygwin -mthreads debugbreak.c | |
18 | ||
19 | */ | |
20 | ||
21 | static char errbuffer[256]; | |
22 | ||
23 | static const char *geterrstr(DWORD errcode) | |
24 | { | |
25 | size_t skip = 0; | |
26 | DWORD chars; | |
27 | chars = FormatMessage( | |
28 | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, | |
29 | NULL, errcode, 0, errbuffer, sizeof(errbuffer)-1, 0); | |
30 | errbuffer[sizeof(errbuffer)-1] = 0; | |
31 | if (chars) { | |
32 | while (errbuffer[chars-1] == '\r' || errbuffer[chars-1] == '\n') { | |
33 | errbuffer[--chars] = 0; | |
34 | } | |
35 | } | |
36 | if (chars && errbuffer[chars-1] == '.') errbuffer[--chars] = 0; | |
37 | if (chars >= 2 && errbuffer[0] == '%' && errbuffer[1] >= '0' | |
38 | && errbuffer[1] <= '9') | |
39 | { | |
40 | skip = 2; | |
41 | while (chars > skip && errbuffer[skip] == ' ') ++skip; | |
42 | if (chars >= skip+2 && errbuffer[skip] == 'i' | |
43 | && errbuffer[skip+1] == 's') | |
44 | { | |
45 | skip += 2; | |
46 | while (chars > skip && errbuffer[skip] == ' ') ++skip; | |
47 | } | |
48 | } | |
49 | if (chars > skip && errbuffer[skip] >= 'A' && errbuffer[skip] <= 'Z') { | |
50 | errbuffer[skip] += 'a' - 'A'; | |
51 | } | |
52 | return errbuffer+skip; | |
53 | } | |
54 | ||
55 | int main(int argc, char *argv[]) | |
56 | { | |
57 | HANDLE proc; | |
58 | unsigned proc_id = 0; | |
59 | BOOL break_result; | |
60 | ||
61 | if (argc != 2) { | |
62 | printf("Usage: debugbreak process_id_number\n"); | |
63 | return 1; | |
64 | } | |
65 | proc_id = (unsigned) strtol(argv[1], NULL, 0); | |
66 | if (proc_id == 0) { | |
67 | printf("Invalid process id %u\n", proc_id); | |
68 | return 1; | |
69 | } | |
70 | proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)proc_id); | |
71 | if (proc == NULL) { | |
72 | DWORD lastError = GetLastError(); | |
73 | printf("Failed to open process %u\n", proc_id); | |
74 | printf("Error code is %lu (%s)\n", (unsigned long)lastError, | |
75 | geterrstr(lastError)); | |
76 | return 1; | |
77 | } | |
78 | break_result = DebugBreakProcess(proc); | |
79 | if (!break_result) { | |
80 | DWORD lastError = GetLastError(); | |
81 | printf("Failed to debug break process %u\n", proc_id); | |
82 | printf("Error code is %lu (%s)\n", (unsigned long)lastError, | |
83 | geterrstr(lastError)); | |
84 | CloseHandle(proc); | |
85 | return 1; | |
86 | } | |
87 | printf("DebugBreak sent successfully to process id %u\n", proc_id); | |
88 | CloseHandle(proc); | |
89 | return 0; | |
90 | } | |
91 | ||
92 | /* END debugbreak.c */ |