Author Topic: Pausing the debugger?  (Read 11479 times)

Offline DrewBoo

  • Multiple posting newcomer
  • *
  • Posts: 110
Pausing the debugger?
« on: March 10, 2008, 05:44:39 pm »
Is there a way to abruptly halt the debugger, so I may add breakpoints or do other debugging tasks?

I'm using Code::Blocks in a unix-like environment, using gcc4.2 to build and gdb6.7 to debug.

When I use gdb on the command line, I can freeze an already running program by hitting Ctrl+C.  I get my debugger prompt right away.  Other IDEs usually have a "pause button" or similar to do that in the graphic environment.

The only enabled debugging button that I see in C::B is "Stop Debugging", which seems to end the entire debugging session.  Have I missed something, or is this feature still in the oven?



Thanks in advance for your help.   :)

Offline thomas

  • Administrator
  • Lives here!
  • *****
  • Posts: 3979
Re: Pausing the debugger?
« Reply #1 on: March 10, 2008, 06:03:17 pm »
I suspect this wasn't implemented because it is not cross-platform.

Quote from: MSDN
Note: SIGINT is not supported for any Win32 application, including Windows 98/Me and Windows NT/2000/XP. When a CTRL+C interrupt occurs, Win32 operating systems generate a new thread to specifically handle that interrupt. This can cause a single-thread application such as UNIX, to become multithreaded, resulting in unexpected behavior.
So... this would have to be implemented Linux-only and hidden under Windows, if anything.
"We should forget about small efficiencies, say about 97% of the time: Premature quotation is the root of public humiliation."

Offline DrewBoo

  • Multiple posting newcomer
  • *
  • Posts: 110
Re: Pausing the debugger?
« Reply #2 on: March 10, 2008, 06:20:27 pm »
I suspect this wasn't implemented because it is not cross-platform.

So... this would have to be implemented Linux-only and hidden under Windows, if anything.

The reply speeds on C:B's forums are amazing.  Thank, you, thomas.

This feature may prove useful enough that I end up implementing it myself.  If I understand things correctly, currently if I debug a program with no breakpoints (and it doesn't crash) I have no way to get into the debugger functionality.  All I can do from C::B is end the debugging session.

Is there someone here I could coordinate with while writing this Windows-exempt feature (I'm not on Linux either...Solaris) so others may take advantage of this?  Or does having a Windows-exempt feature go too far against the team's philosophy?


(As a side-thought, I'm sure there's a similar Windows solution, even if it doesn't involve Ctrl+C)

(Side thought #2, this would allow editing of breakpoints even while the debuggee is running, as it could pause, add the break and immediately resume)

Offline DrewBoo

  • Multiple posting newcomer
  • *
  • Posts: 110
Re: Pausing the debugger?
« Reply #3 on: March 10, 2008, 06:43:08 pm »
I suspect this wasn't implemented because it is not cross-platform.

So... this would have to be implemented Linux-only and hidden under Windows, if anything.

thomas, from looking at the code, it looks like that stop button is indeed supposed to pause first, then end the debugging session if hit again.  (Even works in Windows)

It seems that my issue is that the button currently does nothing. I'm not sure if there's anything left to say, unless someone here is familiar with that issue.

Offline eranif

  • Regular
  • ***
  • Posts: 256
Re: Pausing the debugger?
« Reply #4 on: March 10, 2008, 07:16:43 pm »
I am not familiar with C::B debugger code, but for my debugger code I am using this code, which works fine on Windows & Linux:

Code
bool DbgGdb::Interrupt()
{
if (m_debuggeePid > 0) {
#ifdef __WXMSW__
HANDLE process = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)m_debuggeePid);
BOOL res = DebugBreakProcess(process);
return res == TRUE;
#else
m_observer->UpdateAddLine(wxT("Interrupting debugee process"));
kill(m_debuggeePid, SIGINT);
#endif
}
return true;
}

Note that m_debugeePid is the PID of the child process of gdb, and not gdb itself.

Eran

Offline Jenna

  • Administrator
  • Lives here!
  • *****
  • Posts: 7255
Re: Pausing the debugger?
« Reply #5 on: March 10, 2008, 07:44:56 pm »
It's nearly the same in C::B.

Code
void DebuggerGDB::Break()
{
    // m_Process is PipedProcess I/O; m_Pid is debugger pid
    if (m_pProcess && m_Pid && !IsStopped())
    {
        long pid = m_State.GetDriver()->GetChildPID();
        if (pid <= 0)
            pid = m_Pid; // try poking gdb directly
    #ifndef __WXMSW__
        // non-windows gdb can interrupt the running process. yay!
        if (pid <= 0) // look out for the "fake" PIDs (killall)
            cbMessageBox(_("Unable to stop the debug process!"), _("Error"), wxOK | wxICON_WARNING);
        else
            wxKill(pid, wxSIGINT);
    #else
        // windows gdb can interrupt the running process too. yay!
        bool done = false;
        if (DebugBreakProcessFunc && pid > 0)
        {
            Log(_("Trying to pause the running process..."));
            HANDLE proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
            if (proc)
            {
                DebugBreakProcessFunc(proc); // yay!
                CloseHandle(proc);
                done = true;
            }
            else
                Log(_("Failed."));
        }
    #endif
    }
}

but on windows (at least on my W2K in kvm virtualbox) it does not work.

I'll try to debug it later.

EDIT:
On linux it works: first click -> Pause, second click -> stop.

Offline DrewBoo

  • Multiple posting newcomer
  • *
  • Posts: 110
Re: Pausing the debugger?
« Reply #6 on: March 10, 2008, 08:28:08 pm »
It's nearly the same in C::B.

Code
void DebuggerGDB::Break()
{
    // m_Process is PipedProcess I/O; m_Pid is debugger pid
    if (m_pProcess && m_Pid && !IsStopped())
    {
        long pid = m_State.GetDriver()->GetChildPID();
        if (pid <= 0)
            pid = m_Pid; // try poking gdb directly
    #ifndef __WXMSW__
        // non-windows gdb can interrupt the running process. yay!
        if (pid <= 0) // look out for the "fake" PIDs (killall)
            cbMessageBox(_("Unable to stop the debug process!"), _("Error"), wxOK | wxICON_WARNING);
        else
            wxKill(pid, wxSIGINT);
    #else
        // windows gdb can interrupt the running process too. yay!
        bool done = false;
        if (DebugBreakProcessFunc && pid > 0)
        {
            Log(_("Trying to pause the running process..."));
            HANDLE proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
            if (proc)
            {
                DebugBreakProcessFunc(proc); // yay!
                CloseHandle(proc);
                done = true;
            }
            else
                Log(_("Failed."));
        }
    #endif
    }
}

but on windows (at least on my W2K in kvm virtualbox) it does not work.

I'll try to debug it later.

EDIT:
On linux it works: first click -> Pause, second click -> stop.



Hi, jens.

Yes, I see that now.

Here's the scenario on my Solaris machine:

This is setting pid to 0.
Code
        long pid = m_State.GetDriver()->GetChildPID();


...and here it's set to the debugger's pid.  Unfortunately gdb doesn't respond to SIGINT as we would like it to.
Code
        if (pid <= 0)
            pid = m_Pid; // try poking gdb directly


I have it working with this horrible hack, which is working but certainly isn't reliable and could do Bad Things.

Code
        if (pid <= 0)
        //    pid = m_Pid; // try poking gdb directly
              pid = m_Pid+1; // Assume debuggee's pid is 1 past gdb's pid

mariocup

  • Guest
Re: Pausing the debugger?
« Reply #7 on: April 13, 2008, 04:10:46 pm »
Hi,

I found a workaround how the debugger can be interrupted under windows or other platforms. Select the menu item Debug->Send user command to debugger and type:

Code
interpreter-exec mi interrupt

This will have the same effect like Ctrl+C in the gdb console.

Bye,

Mario