1, can you try to write a simple loop in a hello world like console app, and see the same issue
2, to developers:
I suspect we should use a 64 bit windows API to halt the debugee under 64 bit windows system? I don't have a 64 bit windows at hand.
Currently, we use
DebuggerGDB::DebuggerGDB() :
cbDebuggerPlugin(wxT("GDB/CDB debugger"), wxT("gdb_debugger")),
m_State(this),
m_pProcess(0L),
m_LastExitCode(0),
m_Pid(0),
m_PidToAttach(0),
m_NoDebugInfo(false),
m_StoppedOnSignal(false),
m_pProject(0),
m_stopDebuggerConsoleClosed(false),
m_TemporaryBreak(false),
m_printElements(0)
{
if (!Manager::LoadResource(_T("debugger.zip")))
{
NotifyMissingFile(_T("debugger.zip"));
}
// get a function pointer to DebugBreakProcess under windows (XP+)
#if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501)
kernelLib = LoadLibrary(TEXT("kernel32.dll"));
if (kernelLib)
{
DebugBreakProcessFunc = (DebugBreakProcessApiCall)GetProcAddress(kernelLib, "DebugBreakProcess");
//Windows XP
CreateToolhelp32SnapshotFunc = (CreateToolhelp32SnapshotApiCall)GetProcAddress(kernelLib, "CreateToolhelp32Snapshot");
Process32FirstFunc = (Process32FirstApiCall)GetProcAddress(kernelLib, "Process32First");
Process32NextFunc = (Process32NextApiCall)GetProcAddress(kernelLib, "Process32Next");
}
#endif
}
I'm not sure what happens under a 64 bit windows system.
I've compiled SVN 9744 in 64 bit mode with TDM 4.8.1-3. Pausing the debugger works - sort of. It does not return control to the program, so you can pause the process, but you cannot resume it or debug code.
Trying to interrupt process with pid: 2432; child pid: 2432 gdb pid: 3560
Program received signal SIGTRAP, Trace/breakpoint trap.
In ?? () ()
I used glindsey's code from this topic. After pausing the debugger, this is all I get from the debugger log:
Trying to interrupt process with pid: 448; child pid: 448 gdb pid: 2068
[debug][New Thread 448.0x73c]
[debug]Program received signal SIGTRAP, Trace/breakpoint trap.
[debug][Switching to Thread 448.0x73c]
[debug]0x00007ffe8932c6b1 in ?? ()
[debug]>>>>>>cb_gdb:
Program received signal SIGTRAP, Trace/breakpoint trap.
In ?? () ()
[debug]> bt 30
[debug]#0 0x00007ffe8932c6b1 in ?? ()
[debug]#1 0x00007ffe8935b964 in ?? ()
[debug]#2 0x0000000000000000 in ?? ()
[debug]>>>>>>cb_gdb:
At this moment, I can resume the program and it runs. I can set a breakpoint in the code and it stops there. But I can't get to the program code in which the program is at the moment of pausing (the loop in this example). As you see, the program is not even in the stack trace. If I try to do a Step out anyway, I get:
[debug]> finish
[debug]Run till exit from #0 0x00007ffe8932c6b1 in ?? ()
[debug]0x00007ffe8935b964 in ?? ()
[debug]>>>>>>cb_gdb:
In ?? () ()
[debug]> bt 30
[debug]#0 0x00007ffe8935b964 in ?? ()
[debug]#1 0x0000000000000000 in ?? ()
[debug]>>>>>>cb_gdb:
And the next attempt to Step out:
[debug]> finish
[debug]Warning:
[debug]Cannot insert breakpoint 0.
[debug]Error accessing memory address 0x0: Input/output error.
[debug]Run till exit from #0 0x00007ffe8935b964 in ?? ()
[debug]>>>>>>cb_gdb:
Error accessing memory address 0x0: Input/output error.
[debug]> info frame
[debug]Stack level 0, frame at 0xb2ff38:
[debug] rip = 0x7ffe8935b964; saved rip 0x0
[debug] called by frame at 0xb2ff40
[debug] Arglist at 0xb2ff28, args:
[debug] Locals at 0xb2ff28, Previous frame's sp is 0xb2ff38
[debug] Saved registers:
[debug] rip at 0xb2ff30
[debug]>>>>>>cb_gdb:
In ()
[debug]> bt 30
[debug]#0 0x00007ffe8935b964 in ?? ()
[debug]#1 0x0000000000000000 in ?? ()
I guess the GDB stack sniffer just failed to unwind a frame. This is because when you halt the debugee, it may paused in a system dll which does not have any debug information GDB knows. (Maybe, you can try a more recent GDB to see its sniffer get more robust :))
Do the below steps work after those situation happens? (either in the command line or under C::B)
1, set a bp in the line such as "++x;",
2, you run the continue command
3, the debugee will hit this breakpoint.
I used glindsey's code from this topic. After pausing the debugger, this is all I get from the debugger log:
....
At this moment, I can resume the program and it runs. I can set a breakpoint in the code and it stops there. But I can't get to the program code in which the program is at the moment of pausing (the loop in this example). As you see, the program is not even in the stack trace.
...
Oh, it looks like you can hit the BP, which verify my guess.
I can't get to the program code
This means GDB can't map the instruction address to source code location. :)
Can you post a log from a command ling gdb session?
I've compiled the latest gdb 7.7.1 but it didn't help. Seems it's a limitation of gdb on 64-bit windows.
gdb log below.
Reading symbols from ttt.exe...done.
(gdb) r
Starting program: c:\C\MinGW\MSYS\home\Greg\gdb-7.7.1\_build\bin\ttt.exe
[New Thread 10800.0x1a38]
Hello world!
0... Pausing for a second...
1... Pausing for a second...
2... Pausing for a second...
3... Pausing for a second...
[New Thread 10800.0x1588]
Program received signal SIGINT, Interrupt.
[Switching to Thread 10800.0x1588]
0x0000000077a449f2 in KERNEL32!CtrlRoutine ()
from C:\Windows\system32\kernel32.dll
(gdb) bt
#0 0x0000000077a449f2 in KERNEL32!CtrlRoutine ()
from C:\Windows\system32\kernel32.dll
#1 0x0000000077a059ed in KERNEL32!BaseThreadInitThunk ()
from C:\Windows\system32\kernel32.dll
#2 0x0000000077c3c541 in ntdll!RtlUserThreadStart ()
from C:\Windows\system32\ntdll.dll
#3 0x0000000000000000 in ?? ()
(gdb) c
Continuing.
[Thread 10800.0x1588 exited with code 0]
4... Pausing for a second...
5... Pausing for a second...
6... Pausing for a second...
[New Thread 10800.0x1c60]
Program received signal SIGINT, Interrupt.
[Switching to Thread 10800.0x1c60]
0x0000000077a449f2 in KERNEL32!CtrlRoutine ()
from C:\Windows\system32\kernel32.dll
(gdb) bt
#0 0x0000000077a449f2 in KERNEL32!CtrlRoutine ()
from C:\Windows\system32\kernel32.dll
#1 0x0000000077a059ed in KERNEL32!BaseThreadInitThunk ()
from C:\Windows\system32\kernel32.dll
#2 0x0000000077c3c541 in ntdll!RtlUserThreadStart ()
from C:\Windows\system32\ntdll.dll
#3 0x0000000000000000 in ?? ()
(gdb) b 13
Breakpoint 1 at 0x401571: file ttt.cpp, line 13.
(gdb) c
Continuing.
[Switching to Thread 10800.0x1a38]
Breakpoint 1, main () at ttt.cpp:13
13 ++x;
(gdb)
I see some source code in GDB: windows-nat.c
/* Wait for interesting events to occur in the target process. */
static ptid_t
windows_wait (struct target_ops *ops,
ptid_t ptid, struct target_waitstatus *ourstatus, int options)
{
int pid = -1;
target_terminal_ours ();
/* We loop when we get a non-standard exception rather than return
with a SPURIOUS because resume can try and step or modify things,
which needs a current_thread->h. But some of these exceptions mark
the birth or death of threads, which mean that the current thread
isn't necessarily what you think it is. */
while (1)
{
int retval;
/* If the user presses Ctrl-c while the debugger is waiting
for an event, he expects the debugger to interrupt his program
and to get the prompt back. There are two possible situations:
- The debugger and the program do not share the console, in
which case the Ctrl-c event only reached the debugger.
In that case, the ctrl_c handler will take care of interrupting
the inferior. Note that this case is working starting with
Windows XP. For Windows 2000, Ctrl-C should be pressed in the
inferior console.
- The debugger and the program share the same console, in which
case both debugger and inferior will receive the Ctrl-c event.
In that case the ctrl_c handler will ignore the event, as the
Ctrl-c event generated inside the inferior will trigger the
expected debug event.
FIXME: brobecker/2008-05-20: If the inferior receives the
signal first and the delay until GDB receives that signal
is sufficiently long, GDB can sometimes receive the SIGINT
after we have unblocked the CTRL+C handler. This would
lead to the debugger stopping prematurely while handling
the new-thread event that comes with the handling of the SIGINT
inside the inferior, and then stop again immediately when
the user tries to resume the execution in the inferior.
This is a classic race that we should try to fix one day. */
SetConsoleCtrlHandler (&ctrl_c_handler, TRUE);
retval = get_windows_debug_event (ops, pid, ourstatus);
SetConsoleCtrlHandler (&ctrl_c_handler, FALSE);
So, it looks like CTRL+C should work. But I don't know how to send a CTRL+C from Codeblocks(32bit) to GDB(64bit).