On 15 Jun 2006 11:04:56 -0400, Christopher Faylor wrote:
>Lacking the ability to interrupt a running program severely limits
>gdb's usefulness. Fortunately there's a workaround available.
Yep. Use a console window.
Maybe I haven't been clear. THIS DOES NOT WORK.
Compile the below hellowin.c program with the m$ visual C compiler.
Start it up using gdb. Run it, press CTRL-C, NOTHING HAPPENS.
/* BEGIN hellowin.c */
/* compile with "cl -o hellowin.exe hellowin.c user32.lib" */
#include <windows.h>
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR
lpCmdLine,
int nCmdShow)
{
MessageBox(NULL, "Hello, world!", "", MB_OK);
return 0;
}
/* END hellowin.c */
Now if you have such a program compiled with the m$ compiler for
which you do not have the source and such a program is loading a DLL
plugin built with cygwin that you're trying to debug then CTRL-C WILL
NEVER WORK no matter how many console windows you get out.
A console window is also not an option when debugging via a remote X
session or ssh.
On 15 Jun 2006 10:43:23 -0400 , Igor Peshansky wrote:
Does "kill -INT <cygwin_pid>" work?
No.
The workaround would be even better if you didn't need a separate
program.
How about submitting a patch for Cygwin's "kill" (with a new signal,
SIGDBG or SIGDEBUG)? CGF, would you consider such a patch?
That would be nice, for both kill and killall. I provided the very
simple source code in my original message (and included again in this
one for your convenience) so anyone could use it right away or make a
patch if they like. The relevant code is:
HANDLE proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)
winpid_proc_id);
if (proc != NULL) {DebugBreakProcess(proc); CloseHandle(proc);}
On 15 Jun 2006 01:28:59 -0700 , clayne at anodized dot wrote:
BTW Kyle, you can extend your program greatly by using process
enumeration
coupled with strcmp on the image name to find the pid based on a
string and
automatically signal it.
Yes, or you could just use the below two-line shell script:
#!/bin/sh
ps -W | grep "$1" | awk '{print $1}' | xargs -n 1 debugbreak
But honestly I don't think this program should be needed in the
first place.
Neither do I. gdb was not usable for me previously. The console
window option DOES NOT WORK when the program loading the cygwin-built
DLL was compiled with m$ visual C. It is also a non-solution for ssh
users and remote X users.
Here is the simple debugbreak.c source again.
Kyle
/* 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 */
--
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
Problem reports: http://cygwin.com/problems.html
Documentation: http://cygwin.com/docs.html
FAQ: http://cygwin.com/faq/