Date: Thu, 7 Nov 1996 09:50:48 +0100 (MET) From: Robert Hoehne To: DJGPP workers Subject: Patch for dbgcom.c Message-Id: Mime-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII 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 #include #include + #include + #include 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 %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; }