From mboxrd@z Thu Jan 1 00:00:00 1970 From: Keith Seitz To: Scott A Sumner Cc: insight@sourceware.cygnus.com, jmills@tga.com, bgat@open-widgets.com Subject: Re: Ctrl-C strange behavior Date: Thu, 04 May 2000 08:58:00 -0000 Message-id: <39119E31.504940FF@firetalk.com> References: <20000503.195747.-291705.0.sasumner@juno.com> X-SW-Source: 2000-q2/msg00177.html 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