www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/1999/05/23/05:22:36

Date: Sun, 23 May 1999 12:20:02 +0300 (IDT)
From: Eli Zaretskii <eliz AT is DOT elta DOT co DOT il>
X-Sender: eliz AT is
To: Robert Hoehne <robert DOT hoehne AT gmx DOT net>
cc: djgpp-workers AT delorie DOT com
Subject: Re: gdb 4.18 for DJGPP (alpha)
In-Reply-To: <199905201928.WAA12750@is.elta.co.il>
Message-ID: <Pine.SUN.3.91.990523121928.26578B-100000@is>
MIME-Version: 1.0
Reply-To: djgpp-workers AT delorie DOT com
X-Mailing-List: djgpp-workers AT delorie DOT com
X-Unsubscribes-To: listserv AT delorie DOT com

Some more changes and comments about gdb418s.zip:

 - "maintenance dump-me" wasn't working because it raised SIGQUIT
   which by default is ignored.  Patches below.

 - The produced gdb.ini references a directory ../mmalloc which
   doesn't exist in gdb418s.zip.  This causes an annoying warning each
   time you say "gdb gdb.exe".  I think that either mmalloc should be
   filtered out when gdb.ini is generated, or an empty mmalloc
   directory should be added to gdb418s.

   On the other hand, the ../readline directory should probably be
   included in gdb.ini.

 - SIGQUIT and the alignment check exception were not mentioned in
   sig_map[] on go32-nat.c; I added them.  Now whenever you press
   Ctrl-\, GDB correctly says that the program got SIGQUIT.

   I also see that SIGTIMR (fake exception number 0x78) is not there
   either, and GPF is mapped to TARGET_SIGNAL_ABRT, not SEGV.  Is this
   intentional?

   (I didn't build GDB with the debug support that is in DJ's CVS yet,
   so maybe these problems are solved there somehow.)

 - I added save/restore of the current directory to go32_wait.  Since
   GDB keeps track of the current directory for different purposes, it
   becomes confused when the debuggee changes directory behind its
   back.  And the debuggee could become confused if GDB changes the
   directory (e.g. because the user typed "cd foo").

 - The code which switched GDB's stdin/stdout to text mode was not
   enough to deal with this nuisance.  The problem is that when GDB
   calls setmode, the returned info is about GDB's own stdin/stdout,
   not about that of the debuggee.  So setting stdin/stdout to text
   mode inside go32_terminal_ours indeed switched the console device
   into cooked mode and thus corrected the problem whereby GDB was
   wedged, but the code inside go32_terminal_inferior failed to switch
   the console device back into raw mode, because the value returned
   by setmode and saved by go32_terminal_ours was O_TEXT.

   We actually don't care about text/binary modes here, because the
   debugger and the debuggee have two separate copies of file handles.
   What we do care about is that the console device should be in
   cooked mode while in the debugger, but should be switched to
   whatever mode the debuggee set it when we resume it.  So I rewrote
   go32_terminal_inferior and go32_terminal_ours to save and restore
   the raw/cooked mode of the console device.

   I also added go32_terminal_info to report the console device mode.

   See the diffs below (which include some minor changes to make the
   printed output prettier).

 - The "attach" command would crash GDB, because target.to_attach was
   a null pointer.  I added a trivial function that throws an error.

*** gdb/maint.c~0	Fri Jun 13 17:30:06 1997
--- gdb/maint.c	Thu May 20 21:33:42 1999
*************** maintenance_dump_me (args, from_tty)
*** 99,105 ****
--- 99,110 ----
  {
    if (query ("Should GDB dump core? "))
      {
+ #ifdef __DJGPP__
+       /* SIG_DFL for SIGQUIT is the same as SIG_IGN.  */
+       signal (SIGQUIT, __djgpp_traceback_exit);
+ #else
        signal (SIGQUIT, SIG_DFL);
+ #endif
        kill (getpid (), SIGQUIT);
      }
  }
*** gdb/go32-nat.c~1	Wed May 19 18:38:14 1999
--- gdb/go32-nat.c	Sat May 22 22:10:12 1999
*************** Foundation, Inc., 59 Temple Place - Suit
*** 33,38 ****
--- 33,39 ----
  #include <stdlib.h>
  #include <string.h>
  #include <unistd.h>
+ #include <dpmi.h>
  #include <debug/v2load.h>
  #include <debug/dbgcom.h>
  
*************** sig_map[] =
*** 295,301 ****
  {
    0, TARGET_SIGNAL_FPE,
    1, TARGET_SIGNAL_TRAP,
!   2, TARGET_SIGNAL_UNKNOWN,
    3, TARGET_SIGNAL_TRAP,
    4, TARGET_SIGNAL_FPE,
    5, TARGET_SIGNAL_SEGV,
--- 296,305 ----
  {
    0, TARGET_SIGNAL_FPE,
    1, TARGET_SIGNAL_TRAP,
!   /* Exception 2 is triggered by the NMI.  DJGPP handles it as SIGILL,
!      but I think SIGBUS is better, since the NMI is usually activated
!      as a result of a memory parity check failure.  */
!   2, TARGET_SIGNAL_BUS,
    3, TARGET_SIGNAL_TRAP,
    4, TARGET_SIGNAL_FPE,
    5, TARGET_SIGNAL_SEGV,
*************** sig_map[] =
*** 309,317 ****
--- 313,323 ----
    13, TARGET_SIGNAL_ABRT,
    14, TARGET_SIGNAL_SEGV,
    16, TARGET_SIGNAL_FPE,
+   17, TARGET_SIGNAL_BUS,
    31, TARGET_SIGNAL_ILL,
    0x75, TARGET_SIGNAL_FPE,
    0x79, TARGET_SIGNAL_INT,
+   0x7a, TARGET_SIGNAL_QUIT,
    0x1b, TARGET_SIGNAL_INT,
    -1, -1
  };
*************** sig_map[] =
*** 319,325 ****
  static void
  go32_open (char *name, int from_tty)
  {
!   printf_unfiltered ("Use the `run' command to run go32 programs\n");
  }
  
  static void
--- 325,331 ----
  static void
  go32_open (char *name, int from_tty)
  {
!   printf_unfiltered ("Done.  Use the \"run\" command to run the program.\n");
  }
  
  static void
*************** go32_close (int quitting)
*** 330,336 ****
  static void
  go32_attach (char *args, int from_tty)
  {
!   printf_unfiltered ("Use the `run' command to run go32 programs\n");
  }
  
  static void
--- 336,344 ----
  static void
  go32_attach (char *args, int from_tty)
  {
!   error ("\
! You cannot attach to a running program on this platform.\n\
! Use the `run' command to run DJGPP programs.");
  }
  
  static void
*************** go32_resume (int pid, int step, enum tar
*** 346,351 ****
--- 354,361 ----
      resume_is_step = step;
    }
  
+ static char child_cwd[FILENAME_MAX];
+ 
  static int
  go32_wait (int pid, struct target_waitstatus *status)
  {
*************** go32_wait (int pid, struct target_waitst
*** 356,361 ****
--- 366,380 ----
    else
      a_tss.tss_eflags &= 0xfeff;
  
+   /* The child might change working directory behind our back.  The
+      GDB users won't like the side effects of that when they work with
+      relative file names, and GDB might be confused by its current
+      directory not being in sync with the truth.  So we always make a
+      point of changing back to where GDB thinks is its cwd, when we
+      return control to the debugger, but restore child's cwd before we
+      run it.  */
+   chdir (child_cwd);
+ 
  #if __DJGPP_MINOR__ < 3
    save_npx ();
  #endif
*************** go32_wait (int pid, struct target_waitst
*** 364,369 ****
--- 383,391 ----
    load_npx ();
  #endif
  
+   getcwd (child_cwd, sizeof (child_cwd)); /* in case it has changed */
+   chdir (current_directory);
+ 
    if (a_tss.tss_irqn == 0x21)
      {
        status->kind = TARGET_WAITKIND_EXITED;
*************** go32_fetch_registers (int regno)
*** 418,424 ****
  			 (char *) &npx.reg + regno_mapping[regno].tss_ofs);
        else
  	{
! 	  printf_unfiltered ("Invalid register in go32_fetch_register(%d)",
  			     regno);
  	  exit (1);
  	}
--- 440,446 ----
  			 (char *) &npx.reg + regno_mapping[regno].tss_ofs);
        else
  	{
! 	  printf_unfiltered ("Invalid register %d in go32_fetch_register\n",
  			     regno);
  	  exit (1);
  	}
*************** store_register (int regno)
*** 439,445 ****
      rp = (char *) &npx + regno_mapping[regno].tss_ofs;
    else
      {
!       printf_unfiltered ("Invalid register in store_register(%d)", regno);
        exit (1);
      }
    memcpy (rp, v, regno_mapping[regno].size);
--- 461,467 ----
      rp = (char *) &npx + regno_mapping[regno].tss_ofs;
    else
      {
!       printf_unfiltered ("Invalid register %d in store_register\n", regno);
        exit (1);
      }
    memcpy (rp, v, regno_mapping[regno].size);
*************** go32_xfer_memory (CORE_ADDR memaddr, cha
*** 495,501 ****
  static void
  go32_files_info (struct target_ops *target)
  {
!   printf_unfiltered ("You are running a DJGPP V2 program\n");
  }
  
  static void
--- 517,523 ----
  static void
  go32_files_info (struct target_ops *target)
  {
!   printf_unfiltered ("You are running a DJGPP V2 program.\n");
  }
  
  static void
*************** ignore (void)
*** 569,579 ****
  {
  }
  
- static void
- ignore2 (char *a, int b)
- {
- }
- 
  /* Hardware watchpoint support.  */
  
  #define DR_STATUS 6
--- 591,596 ----
*************** go32_insert_hw_breakpoint (CORE_ADDR add
*** 823,861 ****
    return 0;
  }
  
! static int inf_flags_valid = 0;
! static int inf_in_flag;
! static int inf_out_flag;
  
  static void
  go32_terminal_init (void)
  {
!   /* Save the filemodes for stdin/stout */
!   inf_in_flag = setmode(0, 0);
!   setmode(0, inf_in_flag);
!   inf_out_flag = setmode(1, 0);
!   setmode(1, inf_out_flag);
!   inf_flags_valid = 1;
  }
  
  static void
  go32_terminal_inferior (void)
  {
!   /* set the filemodes for stdin/stdout of the inferior */
!   if (inf_flags_valid)
!   {
!     setmode(0, inf_in_flag);
!     setmode(1, inf_out_flag);
!   }
  }
  
  static void
  go32_terminal_ours (void)
  {
!   /* Switch to text mode on stdin/stdout always on the gdb terminal and
!      save the inferior modes to be restored later */
!   inf_in_flag = setmode(0, O_TEXT);
!   inf_out_flag = setmode(1, O_TEXT);
  }
  
  static void
--- 840,925 ----
    return 0;
  }
  
! /* Put the device open on handle FD into either raw or cooked
!    mode, return 1 if it was in raw mode, zero otherwise.  */
! 
! static int
! device_mode (int fd, int raw_p)
! {
!   int oldmode, newmode;
!   __dpmi_regs regs;
! 
!   regs.x.ax = 0x4400;
!   regs.x.bx = fd;
!   __dpmi_int(0x21, &regs);
!   if (regs.x.flags & 1)
!     return -1;
!   newmode = oldmode = regs.x.dx;
! 
!   if (raw_p)
!     newmode |= 0x20;
!   else
!     newmode &= ~0x20;
! 
!   if (oldmode & 0x80)	/* Only for character dev */
!   {
!     regs.x.ax = 0x4401;
!     regs.x.bx = fd;
!     regs.x.dx = newmode & 0xff;   /* Force upper byte zero, else it fails */
!     __dpmi_int(0x21, &regs);
!     if (regs.x.flags & 1)
!       return -1;
!   }
!   return (oldmode & 0x20) == 0x20;
! }
! 
! 
! static int inf_mode_valid = 0;
! static int inf_terminal_mode;
! 
! /* This semaphore is needed because, amazingly enough, GDB calls
!    target.to_terminal_ours more than once after the inferior stops.
!    But we need the information from the first call only, since the
!    second call will always see GDB's own cooked terminal.  */
! static int terminal_is_ours = 1;
  
  static void
  go32_terminal_init (void)
  {
!   inf_mode_valid = 0;	/* reinitialize, in case they are restarting child */
!   terminal_is_ours = 1;
! }
! 
! static void
! go32_terminal_info (char *args, int from_tty)
! {
!   printf_unfiltered ("Inferior's terminal is in %s mode.\n",
! 		     !inf_mode_valid
! 		     ? "default" : inf_terminal_mode ? "raw" : "cooked");
  }
  
  static void
  go32_terminal_inferior (void)
  {
!   /* set the console device of the inferior to whatever mode
!      (raw or cooked) we found it last time */
!   if (inf_mode_valid)
!     device_mode (0, inf_terminal_mode);
!   terminal_is_ours = 0;
  }
  
  static void
  go32_terminal_ours (void)
  {
!   /* Switch to cooked mode on the gdb terminal and save the inferior
!      terminal mode to be restored when it is resumed */
!   if (!terminal_is_ours)
!     {
!       inf_terminal_mode = device_mode (0, 0);
!       if (inf_terminal_mode != -1)
! 	inf_mode_valid = 1;
!       terminal_is_ours = 1;
!     }
  }
  
  static void
*************** init_go32_ops (void)
*** 867,872 ****
--- 931,937 ----
      "Program loaded by djgpp, when gdb is used as an external debugger";
    go32_ops.to_open = go32_open;
    go32_ops.to_close = go32_close;
+   go32_ops.to_attach = go32_attach;
    go32_ops.to_detach = go32_detach;
    go32_ops.to_resume = go32_resume;
    go32_ops.to_wait = go32_wait;
*************** init_go32_ops (void)
*** 881,887 ****
    go32_ops.to_terminal_inferior = go32_terminal_inferior;
    go32_ops.to_terminal_ours_for_output = ignore;
    go32_ops.to_terminal_ours = go32_terminal_ours;
!   go32_ops.to_terminal_info = ignore2;
    go32_ops.to_kill = go32_kill_inferior;
    go32_ops.to_create_inferior = go32_create_inferior;
    go32_ops.to_mourn_inferior = go32_mourn_inferior;
--- 946,952 ----
    go32_ops.to_terminal_inferior = go32_terminal_inferior;
    go32_ops.to_terminal_ours_for_output = ignore;
    go32_ops.to_terminal_ours = go32_terminal_ours;
!   go32_ops.to_terminal_info = go32_terminal_info;
    go32_ops.to_kill = go32_kill_inferior;
    go32_ops.to_create_inferior = go32_create_inferior;
    go32_ops.to_mourn_inferior = go32_mourn_inferior;
*************** init_go32_ops (void)
*** 894,899 ****
--- 959,967 ----
    go32_ops.to_has_registers = 1;
    go32_ops.to_has_execution = 1;
    go32_ops.to_magic = OPS_MAGIC;
+ 
+   /* Initialize child's cwd with the current one.  */
+   getcwd (child_cwd, sizeof (child_cwd));
  }
  
  void

- Raw text -


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