From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 24897 invoked by alias); 1 May 2009 17:50:38 -0000 Received: (qmail 24882 invoked by uid 22791); 1 May 2009 17:50:37 -0000 X-SWARE-Spam-Status: No, hits=0.7 required=5.0 tests=AWL,BAYES_00,RCVD_IN_JMF_BL,SARE_SUB_GETRID,SPF_SOFTFAIL X-Spam-Check-By: sourceware.org Received: from mtaout4.012.net.il (HELO mtaout3.012.net.il) (84.95.2.10) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 01 May 2009 17:50:30 +0000 Received: from conversion-daemon.i_mtaout3.012.net.il by i_mtaout3.012.net.il (HyperSendmail v2004.12) id <0KIZ00L007XZHM00@i_mtaout3.012.net.il> for gdb-patches@sourceware.org; Fri, 01 May 2009 20:50:27 +0300 (IDT) Received: from HOME-C4E4A596F7 ([77.127.230.216]) by i_mtaout3.012.net.il (HyperSendmail v2004.12) with ESMTPA id <0KIZ008NF87ZB360@i_mtaout3.012.net.il>; Fri, 01 May 2009 20:50:27 +0300 (IDT) Date: Fri, 01 May 2009 17:50:00 -0000 From: Eli Zaretskii Subject: Re: Can we get rid of go32_stop? (and its normal_stop call?) In-reply-to: <83r5z8darm.fsf@gnu.org> To: pedro@codesourcery.com, gdb-patches@sourceware.org Reply-to: Eli Zaretskii Message-id: <83my9wd85y.fsf@gnu.org> References: <200905011514.27632.pedro@codesourcery.com> <83vdokddvk.fsf@gnu.org> <200905011724.36973.pedro@codesourcery.com> <83r5z8darm.fsf@gnu.org> X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2009-05/txt/msg00035.txt.bz2 > Date: Fri, 01 May 2009 19:54:21 +0300 > From: Eli Zaretskii > Cc: gdb-patches@sourceware.org > > > From: Pedro Alves > > Date: Fri, 1 May 2009 17:24:36 +0100 > > > > IMO, it would be nice to paste your description below at the top of > > go32-nat.c. > > Okay, I will do it some time soon. Done with the following patch: 2009-05-01 Eli Zaretskii * go32-nat.c: Add comments about dirty secrets of DJGPP debugging. Index: gdb/go32-nat.c =================================================================== RCS file: /cvs/src/src/gdb/go32-nat.c,v retrieving revision 1.72 diff -u -r1.72 go32-nat.c --- gdb/go32-nat.c 1 May 2009 08:14:00 -0000 1.72 +++ gdb/go32-nat.c 1 May 2009 17:44:32 -0000 @@ -18,6 +18,70 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ +/* To whomever it may concern, here's a general description of how + debugging in DJGPP works, and the special quirks GDB does to + support that. + + When the DJGPP port of GDB is debugging a DJGPP program natively, + there aren't 2 separate processes, the debuggee and GDB itself, as + on other systems. (This is DOS, where there can only be one active + process at any given time, remember?) Instead, GDB and the + debuggee live in the same process. So when GDB calls + go32_create_inferior below, and that function calls edi_init from + the DJGPP debug support library libdbg.a, we load the debuggee's + executable file into GDB's address space, set it up for execution + as the stub loader (a short real-mode program prepended to each + DJGPP executable) normally would, and do a lot of preparations for + swapping between GDB's and debuggee's internal state, primarily wrt + the exception handlers. This swapping happens every time we resume + the debuggee or switch back to GDB's code, and it includes: + + . swapping all the segment registers + . swapping the PSP (the Program Segment Prefix) + . swapping the signal handlers + . swapping the exception handlers + . swapping the FPU status + . swapping the 3 standard file handles (more about this below) + + Then running the debuggee simply means longjmp into it where its PC + is and let it run until it stops for some reason. When it stops, + GDB catches the exception that stopped it and longjmp's back into + its own code. All the possible exit points of the debuggee are + watched; for example, the normal exit point is recognized because a + DOS program issues a special system call to exit. If one of those + exit points is hit, we mourn the inferior and clean up after it. + Cleaning up is very important, even if the process exits normally, + because otherwise we might leave behind traces of previous + execution, and in several cases GDB itself might be left hosed, + because all the exception handlers were not restored. + + Swapping of the standard handles (in redir_to_child and + redir_to_debugger) is needed because, since both GDB and the + debuggee live in the same process, as far as the OS is concerned, + the share the same file table. This means that the standard + handles 0, 1, and 2 point to the same file table entries, and thus + are connected to the same devices. Therefore, if the debugger + redirects its standard output, the standard output of the debuggee + is also automagically redirected to the same file/device! + Similarly, if the debuggee redirects its stdout to a file, you + won't be able to see debugger's output (it will go to the same file + where the debuggee has its output); and if the debuggee closes its + standard input, you will lose the ability to talk to debugger! + + For this reason, every time the debuggee is about to be resumed, we + call redir_to_child, which redirects the standard handles to where + the debuggee expects them to be. When the debuggee stops and GDB + regains control, we call redir_to_debugger, which redirects those 3 + handles back to where GDB expects. + + Note that only the first 3 handles are swapped, so if the debuggee + redirects or closes any other handles, GDB will not notice. In + particular, the exit code of a DJGPP program forcibly closes all + file handles beyond the first 3 ones, so when the debuggee exits, + GDB currently loses its stdaux and stdprn streams. Fortunately, + GDB does not use those as of this writing, and will never need + to. */ + #include #include "defs.h"