binutils-gdb/gdb/inf-child.h
Simon Marchi 737358ba1e gdb: maybe unpush target from old inferior in inf_child_target::follow_exec
I realized that with "follow-exec-mode == new", the process target
stayed pushed in the original inferior.  This can cause a small
incoherence:

    $ ./gdb -q -nx --data-directory=data-directory -ex "set follow-exec-mode new" --args execer args-for-execer
    Reading symbols from execer...
    (gdb) r
    Starting program: /home/smarchi/build/binutils-gdb/gdb/execer args-for-execer
    I am execer and my argv[1] is: args-for-execer
    process 3562426 is executing new program: /home/smarchi/build/binutils-gdb/gdb/execee
    [New inferior 2]
    [New process 3562426]
    I am execee and my argv[1] is: arg-for-execee
    [Inferior 2 (process 3562426) exited normally]
    (gdb) info inferiors
      Num  Description       Connection           Executable
      1    <null>            1 (native)           /home/smarchi/build/binutils-gdb/gdb/execer
    * 2    <null>                                 /home/smarchi/build/binutils-gdb/gdb/execee
    (gdb) maintenance print target-stack
    The current target stack is:
      - exec (Local exec file)
      - None (None)
    (gdb) inferior 1
    [Switching to inferior 1 [<null>] (/home/smarchi/build/binutils-gdb/gdb/execer)]
    (gdb) maintenance print target-stack
    The current target stack is:
      - native (Native process)
      - exec (Local exec file)
      - None (None)

On exec, when execution continues into inferior 2, the native target
isn't unpushed from inferior 1.  When inferior 2's execution finishes
normally, inf_child_target::mourn_inferior unpushes the native target,
because the native target has been implicitly opened.

I think that if the native target was implicitly opened, it should be
unpushed from inferior 1, just like it is unpushed from an inferior
whose execution terminate.  This patch implements that.

gdb/ChangeLog:

	* inf-child.h (inf_child_target) <follow_exec>: New.
	* inf-child.c (inf_child_target::follow_exec): New.

Change-Id: I782cc08d73d93a990f4e53611107f68b2cb58af1
2021-05-13 15:29:00 -04:00

122 lines
4.1 KiB
C++

/* Base/prototype target for default child (native) targets.
Copyright (C) 2004-2021 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#ifndef INF_CHILD_H
#define INF_CHILD_H
#include "target.h"
#include "process-stratum-target.h"
/* A prototype child target. The client can override it with local
methods. */
class inf_child_target
: public memory_breakpoint_target<process_stratum_target>
{
public:
inf_child_target () = default;
~inf_child_target () override = 0;
const target_info &info () const override;
void close () override;
void disconnect (const char *, int) override;
void fetch_registers (struct regcache *, int) override = 0;
void store_registers (struct regcache *, int) override = 0;
void prepare_to_store (struct regcache *) override;
bool supports_terminal_ours () override;
void terminal_init () override;
void terminal_inferior () override;
void terminal_save_inferior () override;
void terminal_ours_for_output () override;
void terminal_ours () override;
void terminal_info (const char *, int) override;
void interrupt () override;
void pass_ctrlc () override;
void post_startup_inferior (ptid_t) override;
void follow_exec (inferior *follow_inf, ptid_t ptid,
const char *execd_pathname) override;
void mourn_inferior () override;
bool can_run () override;
bool can_create_inferior () override;
void create_inferior (const char *, const std::string &,
char **, int) override = 0;
bool can_attach () override;
void attach (const char *, int) override = 0;
void post_attach (int) override;
char *pid_to_exec_file (int pid) override;
int fileio_open (struct inferior *inf, const char *filename,
int flags, int mode, int warn_if_slow,
int *target_errno) override;
int fileio_pwrite (int fd, const gdb_byte *write_buf, int len,
ULONGEST offset, int *target_errno) override;
int fileio_pread (int fd, gdb_byte *read_buf, int len,
ULONGEST offset, int *target_errno) override;
int fileio_fstat (int fd, struct stat *sb, int *target_errno) override;
int fileio_close (int fd, int *target_errno) override;
int fileio_unlink (struct inferior *inf,
const char *filename,
int *target_errno) override;
gdb::optional<std::string> fileio_readlink (struct inferior *inf,
const char *filename,
int *target_errno) override;
bool use_agent (bool use) override;
bool can_use_agent () override;
protected:
/* Unpush the target if it wasn't explicitly open with "target native"
and there are no live inferiors left. Note: if calling this as a
result of a mourn or detach, the current inferior shall already
have its PID cleared, so it isn't counted as live. That's usually
done by calling either generic_mourn_inferior or
detach_inferior. */
void maybe_unpush_target ();
};
/* Functions for helping to write a native target. */
/* This is for native targets which use a unix/POSIX-style waitstatus. */
extern void store_waitstatus (struct target_waitstatus *, int);
/* Register TARGET as native target and set it up to respond to the
"target native" command. */
extern void add_inf_child_target (inf_child_target *target);
/* target_open_ftype callback for inf-child targets. Used by targets
that want to register an alternative target_info object. Most
targets use add_inf_child_target instead. */
extern void inf_child_open_target (const char *arg, int from_tty);
#endif