Mail Archives: cygwin/2006/06/15/13:39:19
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/
- Raw text -