This is the mail archive of the gdb@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[Jim Blandy <jimb@cygnus.com>] PATCH: don't clear inferior pid after loading program via monitor



Andrew asked me to post some more explanation of the effect of this
change.  It changes the user-visible behavior of every ROM monitor
target (all the *-rom.c files in the `gdb' directory).

Speaking strictly from the user's point of view:

Suppose you connect to a board using a ROM monitor:

  (gdb) target rom68k /dev/ttya
  Remote target rom68k connected to /dev/ttya
  (gdb)

You're now looking at the current state of the board.  `print $pc',
`where', etc. will all work.

Now, suppose you load a file onto the board:

  (gdb) load ./my-program
  .text	: 0x00010000 .. 0x00010bd6
  .data	: 0x00010bd8 .. 0x0001131c
  Transfer rate: 39120 bits in <1 sec, 257 bytes/write.
  (gdb) 

Before my patch, the `load' command on a monitor-based target put GDB
in an inconsistent state.  You could print registers and get a
backtrace.  But the `run' command would start up the program, without
warning you that a program was already running on the board.  And
watchpoints set on expressions including automatic variables would
immediately be deleted, because GDB felt it couldn't figure out
whether the frame containing the automatic variables had been popped
yet.

After my patch, after a load command on a monitor-based target, you
can still print registers and get a backtrace.  Watchpoints work
correctly.  But the `run' command will warn you that a program is
already running on the board, and ask if you really want to start the
program afresh; if you say yes, things work correctly.

This is the same behavior that you'd get using `target remote', so I
think my patch makes GDB behave more consistently.

In the past, some folks have said that they want debugging a remote
target to be as much like debugging on a Unix machine as possible.  I
don't think that's a good principle.  A debugger is a tool for
observing the state of a system, and as such, it should present that
state as accurately as possible.  The debugger should behave similarly
across different systems to the degree that those systems are, in
fact, similar.

Connecting to a stand-alone target board running a ROM monitor or GDB
stub is not the same as debugging a program under Unix:

- Invoking a program on Unix creates an new process (a new virtual
  processor), initializes the process's memory from an executable
  file, and sets it running.  GDB reflects this behavior by
  disallowing register examination, backtraces, and so on:

    (gdb) print $pc
    No registers.
    (gdb) backtrace
    No stack.

  When the user enters a `run' command, GDB creates a new process, in
  a way that resembles the usual mode of invocation as closely as
  possible, and sets it running.

- On a typical target board, there is exactly one physical processor
  with is neither created nor destroyed, with a fixed amount of memory
  at a fixed location.  The ROM monitor is always ready to show you
  memory contents, the register values it will resume with, and so on.
  GDB reflects this behavior by allowing you to print registers and
  get a backtrace as soon as you connect to the target.

  The `load' command should simply load a program's code and data into
  memory, and prepare the monitor to begin executing the program.  It
  shouldn't cripple GDB's ability to examine memory or registers.
  This reflects the reality of what's going on on the board.

  The old behavior, of having `load' disable certain actions, makes no
  sense.  After loading the program, the board has simply had some of
  its memory and registers initialized; the monitor is still there,
  ready to let the user examine the new state of the board.

The last thing I want is for my debugger to throw up arbitrary
restrictions on what I can do for the sake of emulating a situation
I'm not in.

------- Start of forwarded message -------
From: Jim Blandy <jimb@cygnus.com>
To: gdb-patches@sources.redhat.com
Subject: PATCH: don't clear inferior pid after loading program via monitor
Message-Id: <20010913225011.CB98B5E9D8@zwingli.cygnus.com>
Date: Thu, 13 Sep 2001 17:50:11 -0500 (EST)


monitor.c seems to be unmaintained, so I've committed this.

2001-09-13  Jim Blandy  <jimb@redhat.com>

	* monitor.c (monitor_load): Don't delete symtab users, or reset
	inferior_ptid.
	
Index: gdb/monitor.c
===================================================================
RCS file: /cvs/src/src/gdb/monitor.c,v
retrieving revision 1.29
diff -c -r1.29 monitor.c
*** gdb/monitor.c	2001/09/13 18:53:42	1.29
--- gdb/monitor.c	2001/09/13 22:45:44
***************
*** 2206,2220 ****
    if (exec_bfd)
      write_pc (bfd_get_start_address (exec_bfd));
  
!   inferior_ptid = null_ptid ;	/* No process now */
  
!   /* This is necessary because many things were based on the PC at the
!      time that we attached to the monitor, which is no longer valid
!      now that we have loaded new code (and just changed the PC).
!      Another way to do this might be to call normal_stop, except that
!      the stack may not be valid, and things would get horribly
!      confused... */
!   clear_symtab_users ();
  }
  
  static void
--- 2206,2224 ----
    if (exec_bfd)
      write_pc (bfd_get_start_address (exec_bfd));
  
!   /* There used to be code here which would clear inferior_ptid and
!      call clear_symtab_users.  None of that should be necessary:
!      monitor targets should behave like remote protocol targets, and
!      since generic_load does none of those things, this function
!      shouldn't either.
  
!      Furthermore, clearing inferior_ptid is *incorrect*.  After doing
!      a load, we still have a valid connection to the monitor, with a
!      live processor state to fiddle with.  The user can type
!      `continue' or `jump *start' and make the program run.  If they do
!      these things, however, GDB will be talking to a running program
!      while inferior_ptid is null_ptid; this makes things like
!      reinit_frame_cache very confused.  */
  }
  
  static void

------- End of forwarded message -------


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]