This is the mail archive of the insight@sourceware.cygnus.com mailing list for the Insight project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Ctrl-C strange behavior


Scott A Sumner wrote:
> 
> My problem:  If my target runs at full speed, I have no way to tell
> Insight I want to break execution wherever it happens to be.  As soon as
> I hit the continue button, Insight changes the cursor to an hourglass and
> just hangs (if I don't have a breakpoint set that execution will hit).  I
> can't do anything except kill gdb and restart it.  I want to press the
> stop button but as Insight appears to be hung at this point, it doesn't
> work.  This is *extremely* annoying; anyone have any idea why it does
> this and what the solution/workaround might be?

The problem which everyone is seeing is the same. Chris Faylor has
already pointed out a very likely fix for the problem. Allow me to
vent^H^H^H^Hexplain what's happening.

(Some of this may be a little out of date: it's been a while since I've
looked at this code.)
The real problem is simple: gdb has a minimum of three event loops: the
gui's event loop or the command processor's event loop, two (or more)
target event loops, and there are probably more that I'm neglecting (or
I've erased from my memory).

Cygnus/Red Hat is working to collapse these down to one, but I can tell
you, this is definitely a non-trivial task. Gdb is an OLD program, and
it was state-of-the-art (more or less) for it's time, when the command
line ruled and "GUI" described brownies. Gdb has, with this one
exception, lived quite well. Not many other programs have a lifespan as
long as gdb's, and with such expandability. It really is quite
remarkable when you think about it.

Let me go into a little detail about what these event loops do... The Tk
event loop and the command processor event loops were collapsed many
years ago with Stu Grossman's original gdbtk. These event loops are
responsible for processing user-interface events, like command input
from the command line or window and mouse events from X/Windows. So far
so good. The problem is, now, when someone runs the inferior (let's say
a over a serial line), gdb BLOCKS in a system call to read (), waiting
for the target to take an exception (breakpoint, illegal instructions,
and so on). Now, while this is happening, the UI's event loop cannot
run. So the user observes a "freeze" or "lock-up" in the user interface.
This is not at all noticeable in command-line interfaces, but it is
especially damaging in graphical interfaces like gdbtk.

Stu's initial solution to the problem was to set SIGIO on the socket for
X, running through all the events in the event queue whenever the signal
handler was called. Worked great, except that we could never seem to get
all unices (SunOS4, in particular) to work properly. There was one other
problem, too: interrupting remote targets. When a user requests to
interrupt a remote target, two things can happen: 1) the target ignores
the request (this is the most likely case; there are only a handful of
remotes that know how to interrupt a running target) and 2) the target
stops, sends and exception (SIGINT) to gdb, and gdb exits the target
event loop, returing to wait_for_inferior, and back out to the GUI. This
is the least likely thing to happen. In fact, I've only seen two or
three (remote) targets that could do this.

To make matters worse, we throw Windows into the mix. SIGIO on Windows?
I don't think so. Even if it did, could we find an X socket to attach it
to? Nope, so we had to do something else. The first step was an itimer.
Worked well on unix, but too flaky on Windows/Cygwin32. Sigh.

To make a long story short(er), we use timers on all native unix
targets. Otherwise, we must place explicit calls to ui_loop_hook in the
target event loop, which is scattered all over the place in various
places. For example, all the simulators were modified to make sure that
they call the simulator's os_poll_quit hook. This maps back to
gdb_os_poll_quit in remote-sim.c, which, calls ui_loop_hook at the
beginning. This forces the GUI's event loop to run.

Need to interrupt targets which don't support it? Well, that's a little
tougher. When this happens in the command line, gdb will ask the user if
he wants to detach from the target and stop debugging it. If the user
says "yes", then gdb longjmps () over the read (), back to the
"top_level", the main UI event loop. Well, as you might expect,
longjmp'ing over an interpreter is bad news. That's why ui_loop_hook
returns a value. If this value is non-zero, this tells the caller to
break out of his event loop, because the user wants to force a
disconnect. See the example in do_hardwire_readchar in ser-unix.c. We
modified the blocking call to read () to do one second polls, allowing
the UI to run through the event loop each time. This is why gdbtk gets
choppy when a remote target is running.

Wow. Well, I think I've over answered your question, but now you have a
better understanding of what's going on behind the scenes.

Keith
-- 
Why chat when you can Firetalk?
Firetalk ID: Keith (10320)
www.firetalk.com

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]