X-Spam-Check-By: sourceware.org Mime-Version: 1.0 (Apple Message framework v750) Content-Transfer-Encoding: 7bit Message-Id: Content-Type: text/plain; charset=US-ASCII; delsp=yes; format=flowed To: cygwin AT cygwin DOT com From: Kyle McKay Subject: Re: GDB Ctrl-C Interrupt Fails WORKAROUND Date: Thu, 15 Jun 2006 10:38:57 -0700 X-Mailer: Apple Mail (2.750) Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com 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 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 " 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 #include #include /* 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/