aboutsummaryrefslogtreecommitdiff
path: root/gdb/target/waitstatus.h
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/target/waitstatus.h')
-rw-r--r--gdb/target/waitstatus.h236
1 files changed, 232 insertions, 4 deletions
diff --git a/gdb/target/waitstatus.h b/gdb/target/waitstatus.h
index 4123f42..333863e 100644
--- a/gdb/target/waitstatus.h
+++ b/gdb/target/waitstatus.h
@@ -103,22 +103,250 @@ enum target_waitkind
struct target_waitstatus
{
- enum target_waitkind kind;
+ /* Default constructor. */
+ target_waitstatus () = default;
+
+ /* Copy constructor. */
+
+ target_waitstatus (const target_waitstatus &other)
+ {
+ m_kind = other.m_kind;
+ m_value = other.m_value;
+
+ if (m_kind == TARGET_WAITKIND_EXECD)
+ m_value.execd_pathname = xstrdup (m_value.execd_pathname);
+ }
+
+ /* Move constructor. */
+
+ target_waitstatus (target_waitstatus &&other)
+ {
+ m_kind = other.m_kind;
+ m_value = other.m_value;
+
+ if (m_kind == TARGET_WAITKIND_EXECD)
+ other.m_value.execd_pathname = nullptr;
+
+ other.reset ();
+ }
+
+ /* Copy assignment operator. */
+
+ target_waitstatus &operator= (const target_waitstatus &rhs)
+ {
+ this->reset ();
+ m_kind = rhs.m_kind;
+ m_value = rhs.m_value;
+
+ if (m_kind == TARGET_WAITKIND_EXECD)
+ m_value.execd_pathname = xstrdup (m_value.execd_pathname);
+
+ return *this;
+ }
+
+ /* Move assignment operator. */
+
+ target_waitstatus &operator= (target_waitstatus &&rhs)
+ {
+ this->reset ();
+ m_kind = rhs.m_kind;
+ m_value = rhs.m_value;
+
+ if (m_kind == TARGET_WAITKIND_EXECD)
+ rhs.m_value.execd_pathname = nullptr;
+
+ rhs.reset ();
+
+ return *this;
+ }
+
+ /* Destructor. */
+
+ ~target_waitstatus ()
+ {
+ this->reset ();
+ }
+
+ /* Setters: set the wait status kind plus any associated data. */
+
+ void set_exited (int exit_status)
+ {
+ this->reset ();
+ m_kind = TARGET_WAITKIND_EXITED;
+ m_value.exit_status = exit_status;
+ }
+
+ void set_stopped (gdb_signal sig)
+ {
+ this->reset ();
+ m_kind = TARGET_WAITKIND_STOPPED;
+ m_value.sig = sig;
+ }
+
+ void set_signalled (gdb_signal sig)
+ {
+ this->reset ();
+ m_kind = TARGET_WAITKIND_SIGNALLED;
+ m_value.sig = sig;
+ }
+
+ void set_loaded ()
+ {
+ this->reset ();
+ m_kind = TARGET_WAITKIND_LOADED;
+ }
+
+ void set_forked (ptid_t child_ptid)
+ {
+ this->reset ();
+ m_kind = TARGET_WAITKIND_FORKED;
+ m_value.child_ptid = child_ptid;
+ }
+
+ void set_vforked (ptid_t child_ptid)
+ {
+ this->reset ();
+ m_kind = TARGET_WAITKIND_VFORKED;
+ m_value.child_ptid = child_ptid;
+ }
+
+ void set_execd (gdb::unique_xmalloc_ptr<char> execd_pathname)
+ {
+ this->reset ();
+ m_kind = TARGET_WAITKIND_EXECD;
+ m_value.execd_pathname = execd_pathname.release ();
+ }
+
+ void set_vfork_done ()
+ {
+ this->reset ();
+ m_kind = TARGET_WAITKIND_VFORK_DONE;
+ }
+
+ void set_syscall_entry (int syscall_number)
+ {
+ this->reset ();
+ m_kind = TARGET_WAITKIND_SYSCALL_ENTRY;
+ m_value.syscall_number = syscall_number;
+ }
+
+ void set_syscall_return (int syscall_number)
+ {
+ this->reset ();
+ m_kind = TARGET_WAITKIND_SYSCALL_RETURN;
+ m_value.syscall_number = syscall_number;
+ }
+
+ void set_spurious ()
+ {
+ this->reset ();
+ m_kind = TARGET_WAITKIND_SPURIOUS;
+ }
+
+ void set_ignore ()
+ {
+ this->reset ();
+ m_kind = TARGET_WAITKIND_IGNORE;
+ }
+
+ void set_no_history ()
+ {
+ this->reset ();
+ m_kind = TARGET_WAITKIND_NO_HISTORY;
+ }
+
+ void set_no_resumed ()
+ {
+ this->reset ();
+ m_kind = TARGET_WAITKIND_NO_RESUMED;
+ }
+
+ void set_thread_created ()
+ {
+ this->reset ();
+ m_kind = TARGET_WAITKIND_THREAD_CREATED;
+ }
+
+ void set_thread_exited (int exit_status)
+ {
+ this->reset ();
+ m_kind = TARGET_WAITKIND_THREAD_EXITED;
+ m_value.exit_status = exit_status;
+ }
+
+ /* Get the kind of this wait status. */
+
+ target_waitkind kind () const
+ {
+ return m_kind;
+ }
+
+ /* Getters for the associated data.
+
+ Getters can only be used if the wait status is of the appropriate kind.
+ See the setters above or the assertions below to know which data is
+ associated to which kind. */
+
+ int exit_status () const
+ {
+ gdb_assert (m_kind == TARGET_WAITKIND_EXITED
+ || m_kind == TARGET_WAITKIND_THREAD_EXITED);
+ return m_value.exit_status;
+ }
+
+ gdb_signal sig () const
+ {
+ gdb_assert (m_kind == TARGET_WAITKIND_STOPPED
+ || m_kind == TARGET_WAITKIND_SIGNALLED);
+ return m_value.sig;
+ }
+
+ ptid_t child_ptid () const
+ {
+ gdb_assert (m_kind == TARGET_WAITKIND_FORKED
+ || m_kind == TARGET_WAITKIND_VFORKED);
+ return m_value.child_ptid;
+ }
+
+ const char *execd_pathname () const
+ {
+ gdb_assert (m_kind == TARGET_WAITKIND_EXECD);
+ return m_value.execd_pathname;
+ }
+
+ int syscall_number () const
+ {
+ gdb_assert (m_kind == TARGET_WAITKIND_SYSCALL_ENTRY
+ || m_kind == TARGET_WAITKIND_SYSCALL_RETURN);
+ return m_value.syscall_number;
+ }
+
+private:
+ /* Reset the wait status to its original state. */
+ void reset ()
+ {
+ if (m_kind == TARGET_WAITKIND_EXECD)
+ xfree (m_value.execd_pathname);
+
+ m_kind = TARGET_WAITKIND_IGNORE;
+ }
+
+ target_waitkind m_kind = TARGET_WAITKIND_IGNORE;
/* Additional information about the event. */
union
{
/* Exit status */
- int integer;
+ int exit_status;
/* Signal number */
enum gdb_signal sig;
/* Forked child pid */
- ptid_t related_pid;
+ ptid_t child_ptid;
/* execd pathname */
char *execd_pathname;
/* Syscall number */
int syscall_number;
- } value;
+ } m_value;
};
/* Extended reasons that can explain why a target/thread stopped for a