delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/1996/11/07/03:55:08

Date: Thu, 7 Nov 1996 09:50:48 +0100 (MET)
From: Robert Hoehne <robert DOT hoehne AT mathematik DOT tu-chemnitz DOT de>
To: DJGPP workers <djgpp-workers AT delorie DOT com>
Subject: Patch for dbgcom.c
Message-Id: <Pine.HPP.3.95.961107094034.1695A-100000@newton.mathematik.tu-chemnitz.de>
Mime-Version: 1.0

Here is a patch for dbgcom.c, which enables all the debuggers,
who use the cleanup_client() function to unload the debugged
program to close all filehandles which can be not closed
by the the debugged program.

This situation can occour, when using the kill from gdb, when
your debugged program has opened some files and not closed
or when the program assumes, that the files will be closed
on exit. This assumption is true only for files, which are
opened with fopen but not for files, which are opened with
open.

The technique is very simple. If the file dbgcom.o is linked 
in your program it installs a hook for the open and close
function with the very great FSEXT functionallity. It watches
every opened file and when cleanup_client() is called, the
table with the handles to be known as opened is compared
with the actual opened files. If there is handle opened and
was not watched so it was opened by the debugge and will
be closed.

This works only, if the debugger does NOT open files with
the _dos_open() or simliar functions, because the bypass
the FSEXT functions.

Robert

*** src/debug/common/dbgcom.c~	Tue Nov  5 16:33:38 1996
--- src/debug/common/dbgcom.c	Tue Nov  5 21:51:12 1996
***************
*** 14,19 ****
--- 14,21 ----
  #include <sys/exceptn.h>
  #include <stubinfo.h>
  #include <sys/farptr.h>
+ #include <sys/fsext.h>
+ #include <io.h>
  
  extern char __libdbg_ident_string[];
  static char *id = __libdbg_ident_string;
***************
*** 605,610 ****
--- 607,613 ----
    __djgpp_app_DS = a_tss.tss_ds;
    app_cs = a_tss.tss_cs;
    edi.app_base = 0;
+   /* Save all the changed signal handlers */
    oldTRAP = signal(SIGTRAP, dbgsig);
    oldSEGV = signal(SIGSEGV, dbgsig);
    oldFPE = signal(SIGFPE, dbgsig);
***************
*** 622,630 ****
--- 625,637 ----
    dos_descriptors[1] = si.psp_selector; 
  }
  
+ static void close_handles(void); /* Forward declaration */
+ 
  void cleanup_client(void)
  {
    int i;
+   /* Close all handles, which may be left open */
+   close_handles();
    for (i=0;i<DOS_DESCRIPTOR_COUNT;i++)
    {
      if (dos_descriptors[i])
***************
*** 655,662 ****
--- 662,827 ----
        __dpmi_free_ldt_descriptor(descriptors[i]);
      }
    }
+   /* Restore all changed signal handlers */
    signal(SIGTRAP, oldTRAP);
    signal(SIGSEGV, oldSEGV);
    signal(SIGFPE, oldFPE);
    signal(SIGINT, oldINT);
+ }
+ 
+ /*
+    Now the FSEXT function to watching the opened files. This is needed,
+    because the debuggee can open files which are not closed and if you
+    do this multiple times, the limit of max opened files is reached.
+ 
+    The watching is done by the FSEXT function by hooking the
+    _open(), _creat() and _close() calls from the libc functions. The
+    only things which are added is in remembering of the files, which
+    are opened (and closed) by debugger. When cleanup_client() is called
+    this list is compared with actual opened files and every file, which
+    was not watched dbg_fsext() is closed.
+ 
+    This technique does not work correct when the debugger uses the lowest
+    routines for opening/creating/closing files which are
+    _dos_open(), _dos_creat(), _dos_creatnew() and _dos_close().
+ */
+ 
+ static unsigned char handles[256];
+ static int in_dbg_fsext = 0;
+ 
+ static void close_handles(void)
+ {
+   __dpmi_regs r;
+   int psp_la;
+   int jft_ofs;
+   int jft_count;
+   int handle;
+ 
+   /* Get our PSP address.  */
+   r.x.ax = 0x6200;
+   __dpmi_int (0x21, &r);
+   psp_la = ( (int)r.x.bx ) << 4;
+ 
+   /* Get the offset of the JFT table by (seg << 4) + offset */
+   jft_ofs = (_farpeekw(_dos_ds, psp_la + 0x36) << 4) +
+             _farpeekw(_dos_ds, psp_la + 0x34);
+ 
+   /* Number of used entries in the JFT table */
+   jft_count = _farpeekw(_dos_ds, psp_la + 0x32);
+ 
+   /* Disable the fsext function */
+   in_dbg_fsext++;
+ 
+   for (handle=0;handle<jft_count;handle++)
+   {
+     if (_farpeekb(_dos_ds,jft_ofs++) != 0xff /* it is an opened handle */
+         && handles[handle] == 0xff /* but not recorded by the fsext function */
+        )
+     { /* it was opened by the debugge */
+ #ifdef DEBUG_DBGCOM
+       fprintf(stderr,"closing %d\n",handle);
+ #endif
+       _close(handle);
+     }
+   }
+ 
+   /* Enable the fsext function */
+   in_dbg_fsext--;
+ }
+ 
+ 
+ static int dbg_fsext(__FSEXT_Fnumber _function_number,
+                       int *_rv, va_list _args)
+ {
+   int attrib,oflag,retval = 0,handle;
+   const char *filename;
+   /* We are called from this function */
+   if (in_dbg_fsext) return 0;
+   switch (_function_number)
+   {
+     default:
+       return 0;
+     case __FSEXT_creat:
+       filename = va_arg(_args,const char *);
+       attrib = va_arg(_args,int);
+       in_dbg_fsext++;
+       retval = _creat(filename,attrib);
+ #ifdef DEBUG_DBGCOM
+       fprintf(stderr,"_creat() => %d\n",retval);
+ #endif
+       in_dbg_fsext--;
+       if (retval != -1)
+       {
+         handles[retval] = retval;
+         __FSEXT_set_function(retval,dbg_fsext);
+       }
+       break;
+     case __FSEXT_open:
+       filename = va_arg(_args,const char *);
+       oflag = va_arg(_args,int);
+       in_dbg_fsext++;
+       retval = _open(filename,oflag);
+ #ifdef DEBUG_DBGCOM
+       fprintf(stderr,"_open(%s) => %d\n",filename,retval);
+ #endif
+       in_dbg_fsext--;
+       if (retval != -1)
+       {
+         handles[retval] = retval;
+         __FSEXT_set_function(retval,dbg_fsext);
+       }
+       break;
+     case __FSEXT_close:
+       handle = va_arg(_args,int);
+       in_dbg_fsext++;
+ #ifdef DEBUG_DBGCOM
+       fprintf(stderr,"_close(%d)\n",handle);
+ #endif
+       retval = _close(handle);
+       in_dbg_fsext--;
+       if (retval == 0)
+       {
+         handles[handle] = 0xff;
+         __FSEXT_set_function(handle,NULL);
+       }
+       break;
+   }
+   *_rv = retval;
+   return 1;
+ }
+ 
+ /* With attribute constructor to be called automaticaly befor main */
+ 
+ static void __attribute__((__constructor__))
+ _init_dbg_fsext(void)
+ {
+   __dpmi_regs r;
+   int i, fd;
+   int psp_la;
+   int jft_ofs;
+   int jft_count;
+ 
+   /* Get our PSP address.  */
+   r.x.ax = 0x6200;
+   __dpmi_int (0x21, &r);
+   psp_la = ( (int)r.x.bx ) << 4;
+ 
+   /* Get the offset of the JFT table by (seg << 4) + offset */
+   jft_ofs = (_farpeekw(_dos_ds, psp_la + 0x36) << 4) +
+             _farpeekw(_dos_ds, psp_la + 0x34);
+ 
+   /* Number of used entries in the JFT table */
+   jft_count = _farpeekw(_dos_ds, psp_la + 0x32);
+ 
+   /* Add the handler for opening/creating files */
+   __FSEXT_add_open_handler(dbg_fsext);
+ 
+   /* Initialize all the handles to 0xff */
+   memset(handles,0xff,sizeof(handles));
+ 
+   /* Get a copy of all already opened handles */
+   movedata(_dos_ds,jft_ofs,_my_ds(),(int)handles,jft_count);
+ 
+   /* enable the fsext function */
+   in_dbg_fsext = 0;
  }


- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019