diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 532c2b99631..2126c335c42 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,23 @@ +2017-10-12 Simon Marchi + + * linux-nat.h (linux_nat_set_delete_thread): New declaration. + * linux-nat.c (linux_nat_delete_thread): New variable. + (lwp_free): Invoke linux_nat_delete_thread if set. + (linux_nat_set_delete_thread): New function. + * aarch64-linux-nat.c (_initialize_aarch64_linux_nat): Assign + thread delete callback. + * arm-linux-nat.c (arm_linux_delete_thread): New function. + (_initialize_arm_linux_nat): Assign thread delete callback. + * s390-linux-nat.c (s390_delete_thread): New function. + (_initialize_s390_nat): Assign thread delete callback. + * x86-linux-nat.c (x86_linux_add_target): Likewise. + * nat/aarch64-linux.c (aarch64_linux_delete_thread): New + function. + * nat/aarch64-linux.h (aarch64_linux_delete_thread): New + declaration. + * nat/x86-linux.c (x86_linux_delete_thread): New function. + * nat/x86-linux.h (x86_linux_delete_thread): New declaration. + 2017-10-09 Tom Tromey * tui/tui-win.c (tui_set_win_height, parse_scrolling_args): Use diff --git a/gdb/aarch64-linux-nat.c b/gdb/aarch64-linux-nat.c index 6ad6f663bfe..4feaec39d91 100644 --- a/gdb/aarch64-linux-nat.c +++ b/gdb/aarch64-linux-nat.c @@ -837,6 +837,7 @@ _initialize_aarch64_linux_nat (void) /* Register the target. */ linux_nat_add_target (t); linux_nat_set_new_thread (t, aarch64_linux_new_thread); + linux_nat_set_delete_thread (t, aarch64_linux_delete_thread); linux_nat_set_new_fork (t, aarch64_linux_new_fork); linux_nat_set_forget_process (t, aarch64_forget_process); linux_nat_set_prepare_to_resume (t, aarch64_linux_prepare_to_resume); diff --git a/gdb/arm-linux-nat.c b/gdb/arm-linux-nat.c index fc66063ce50..8b25ff7f948 100644 --- a/gdb/arm-linux-nat.c +++ b/gdb/arm-linux-nat.c @@ -1202,6 +1202,14 @@ arm_linux_new_thread (struct lwp_info *lp) lp->arch_private = info; } +/* Function to call when a thread is being deleted. */ + +static void +arm_linux_delete_thread (struct arch_lwp_info *arch_lwp) +{ + xfree (arch_lwp); +} + /* Called when resuming a thread. The hardware debug registers are updated when there is any change. */ @@ -1313,6 +1321,7 @@ _initialize_arm_linux_nat (void) /* Handle thread creation and exit. */ linux_nat_set_new_thread (t, arm_linux_new_thread); + linux_nat_set_delete_thread (t, arm_linux_delete_thread); linux_nat_set_prepare_to_resume (t, arm_linux_prepare_to_resume); /* Handle process creation and exit. */ diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog index 5bcd717afe7..1edb8495fd5 100644 --- a/gdb/gdbserver/ChangeLog +++ b/gdb/gdbserver/ChangeLog @@ -1,3 +1,26 @@ +2017-10-12 Simon Marchi + + * linux-aarch64-low.c (the_low_target): Add thread delete + callback. + * linux-arm-low.c (arm_delete_thread): New function. + (the_low_target): Add thread delete callback. + * linux-bfin-low.c (the_low_target): Likewise. + * linux-crisv32-low.c (the_low_target): Likewise. + * linux-low.c (delete_lwp): Invoke delete_thread callback if + set. + * linux-low.h (struct linux_target_ops) : New + field. + * linux-m32r-low.c (the_low_target): Add thread delete callback. + * linux-mips-low.c (mips_linux_delete_thread): New function. + (the_low_target): Add thread delete callback. + * linux-ppc-low.c (the_low_target): Likewise. + * linux-s390-low.c (the_low_target): Likewise. + * linux-sh-low.c (the_low_target): Likewise. + * linux-tic6x-low.c (the_low_target): Likewise. + * linux-tile-low.c (the_low_target): Likewise. + * linux-x86-low.c (the_low_target): Likewise. + * linux-xtensa-low.c (the_low_target): Likewise. + 2017-10-06 Yuanhui Zhang * win32-low.c: Include "common-inferior.h". diff --git a/gdb/gdbserver/linux-aarch64-low.c b/gdb/gdbserver/linux-aarch64-low.c index 334310be579..ed6a9931d2e 100644 --- a/gdb/gdbserver/linux-aarch64-low.c +++ b/gdb/gdbserver/linux-aarch64-low.c @@ -2991,6 +2991,7 @@ struct linux_target_ops the_low_target = aarch64_linux_siginfo_fixup, aarch64_linux_new_process, aarch64_linux_new_thread, + aarch64_linux_delete_thread, aarch64_linux_new_fork, aarch64_linux_prepare_to_resume, NULL, /* process_qsupported */ diff --git a/gdb/gdbserver/linux-arm-low.c b/gdb/gdbserver/linux-arm-low.c index 5a3f465dee1..b27c47e84c4 100644 --- a/gdb/gdbserver/linux-arm-low.c +++ b/gdb/gdbserver/linux-arm-low.c @@ -655,6 +655,14 @@ arm_new_thread (struct lwp_info *lwp) lwp->arch_private = info; } +/* Function to call when a thread is being deleted. */ + +static void +arm_delete_thread (struct arch_lwp_info *arch_lwp) +{ + xfree (arch_lwp); +} + static void arm_new_fork (struct process_info *parent, struct process_info *child) { @@ -1053,6 +1061,7 @@ struct linux_target_ops the_low_target = { NULL, /* siginfo_fixup */ arm_new_process, arm_new_thread, + arm_delete_thread, arm_new_fork, arm_prepare_to_resume, NULL, /* process_qsupported */ diff --git a/gdb/gdbserver/linux-bfin-low.c b/gdb/gdbserver/linux-bfin-low.c index d43b05dd37e..175152c4598 100644 --- a/gdb/gdbserver/linux-bfin-low.c +++ b/gdb/gdbserver/linux-bfin-low.c @@ -136,6 +136,7 @@ struct linux_target_ops the_low_target = { NULL, /* siginfo_fixup */ NULL, /* new_process */ NULL, /* new_thread */ + NULL, /* delete_thread */ NULL, /* new_fork */ NULL, /* prepare_to_resume */ NULL, /* process_qsupported */ diff --git a/gdb/gdbserver/linux-crisv32-low.c b/gdb/gdbserver/linux-crisv32-low.c index 5b3888ea364..79111048fae 100644 --- a/gdb/gdbserver/linux-crisv32-low.c +++ b/gdb/gdbserver/linux-crisv32-low.c @@ -416,6 +416,7 @@ struct linux_target_ops the_low_target = { NULL, /* siginfo_fixup */ NULL, /* new_process */ NULL, /* new_thread */ + NULL, /* delete_thread */ NULL, /* new_fork */ NULL, /* prepare_to_resume */ NULL, /* process_qsupported */ diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c index 54005c1f1d4..a762b8f0818 100644 --- a/gdb/gdbserver/linux-low.c +++ b/gdb/gdbserver/linux-low.c @@ -414,7 +414,12 @@ delete_lwp (struct lwp_info *lwp) debug_printf ("deleting %ld\n", lwpid_of (thr)); remove_thread (thr); - free (lwp->arch_private); + + if (the_low_target.delete_thread != NULL) + the_low_target.delete_thread (lwp->arch_private); + else + gdb_assert (lwp->arch_private == NULL); + free (lwp); } diff --git a/gdb/gdbserver/linux-low.h b/gdb/gdbserver/linux-low.h index 0ece7bc25bf..9c69dece96d 100644 --- a/gdb/gdbserver/linux-low.h +++ b/gdb/gdbserver/linux-low.h @@ -194,6 +194,10 @@ struct linux_target_ops allocate it here. */ void (*new_thread) (struct lwp_info *); + /* Hook to call when a thread is being deleted. If extra per-thread + architecture-specific data is needed, delete it here. */ + void (*delete_thread) (struct arch_lwp_info *); + /* Hook to call, if any, when a new fork is attached. */ void (*new_fork) (struct process_info *parent, struct process_info *child); diff --git a/gdb/gdbserver/linux-m32r-low.c b/gdb/gdbserver/linux-m32r-low.c index b3ee11ac109..b947fa06585 100644 --- a/gdb/gdbserver/linux-m32r-low.c +++ b/gdb/gdbserver/linux-m32r-low.c @@ -135,6 +135,7 @@ struct linux_target_ops the_low_target = { NULL, /* siginfo_fixup */ NULL, /* new_process */ NULL, /* new_thread */ + NULL, /* delete_thread */ NULL, /* new_fork */ NULL, /* prepare_to_resume */ NULL, /* process_qsupported */ diff --git a/gdb/gdbserver/linux-mips-low.c b/gdb/gdbserver/linux-mips-low.c index b4a83b0e21e..ec26c2a8c56 100644 --- a/gdb/gdbserver/linux-mips-low.c +++ b/gdb/gdbserver/linux-mips-low.c @@ -341,6 +341,14 @@ mips_linux_new_thread (struct lwp_info *lwp) lwp->arch_private = info; } +/* Function to call when a thread is being deleted. */ + +static void +mips_linux_delete_thread (struct arch_lwp_info *arch_lwp) +{ + xfree (arch_lwp); +} + /* Create a new mips_watchpoint and add it to the list. */ static void @@ -893,6 +901,7 @@ struct linux_target_ops the_low_target = { NULL, /* siginfo_fixup */ mips_linux_new_process, mips_linux_new_thread, + mips_linux_delete_thread, mips_linux_new_fork, mips_linux_prepare_to_resume }; diff --git a/gdb/gdbserver/linux-ppc-low.c b/gdb/gdbserver/linux-ppc-low.c index 33a9feb12c6..f31a47b5f19 100644 --- a/gdb/gdbserver/linux-ppc-low.c +++ b/gdb/gdbserver/linux-ppc-low.c @@ -3125,6 +3125,7 @@ struct linux_target_ops the_low_target = { NULL, /* siginfo_fixup */ NULL, /* new_process */ NULL, /* new_thread */ + NULL, /* delete_thread */ NULL, /* new_fork */ NULL, /* prepare_to_resume */ NULL, /* process_qsupported */ diff --git a/gdb/gdbserver/linux-s390-low.c b/gdb/gdbserver/linux-s390-low.c index d7aa31c319a..1a4c3407fbc 100644 --- a/gdb/gdbserver/linux-s390-low.c +++ b/gdb/gdbserver/linux-s390-low.c @@ -2830,6 +2830,7 @@ struct linux_target_ops the_low_target = { NULL, /* siginfo_fixup */ NULL, /* new_process */ NULL, /* new_thread */ + NULL, /* delete_thread */ NULL, /* new_fork */ NULL, /* prepare_to_resume */ NULL, /* process_qsupported */ diff --git a/gdb/gdbserver/linux-sh-low.c b/gdb/gdbserver/linux-sh-low.c index ac084c994fa..273062faa08 100644 --- a/gdb/gdbserver/linux-sh-low.c +++ b/gdb/gdbserver/linux-sh-low.c @@ -165,6 +165,7 @@ struct linux_target_ops the_low_target = { NULL, /* siginfo_fixup */ NULL, /* new_process */ NULL, /* new_thread */ + NULL, /* delete_thread */ NULL, /* new_fork */ NULL, /* prepare_to_resume */ NULL, /* process_qsupported */ diff --git a/gdb/gdbserver/linux-tic6x-low.c b/gdb/gdbserver/linux-tic6x-low.c index 8931d699a04..8b2a6f35ca8 100644 --- a/gdb/gdbserver/linux-tic6x-low.c +++ b/gdb/gdbserver/linux-tic6x-low.c @@ -398,6 +398,7 @@ struct linux_target_ops the_low_target = { NULL, /* siginfo_fixup */ NULL, /* new_process */ NULL, /* new_thread */ + NULL, /* delete_thread */ NULL, /* new_fork */ NULL, /* prepare_to_resume */ NULL, /* process_qsupported */ diff --git a/gdb/gdbserver/linux-tile-low.c b/gdb/gdbserver/linux-tile-low.c index ee1f1968364..c5b344bd631 100644 --- a/gdb/gdbserver/linux-tile-low.c +++ b/gdb/gdbserver/linux-tile-low.c @@ -197,6 +197,7 @@ struct linux_target_ops the_low_target = NULL, /* siginfo_fixup */ NULL, /* new_process */ NULL, /* new_thread */ + NULL, /* delete_thread */ NULL, /* new_fork */ NULL, /* prepare_to_resume */ NULL, /* process_qsupported */ diff --git a/gdb/gdbserver/linux-x86-low.c b/gdb/gdbserver/linux-x86-low.c index 49f6b2d4892..9597502dfca 100644 --- a/gdb/gdbserver/linux-x86-low.c +++ b/gdb/gdbserver/linux-x86-low.c @@ -2867,6 +2867,7 @@ struct linux_target_ops the_low_target = x86_siginfo_fixup, x86_linux_new_process, x86_linux_new_thread, + x86_linux_delete_thread, x86_linux_new_fork, x86_linux_prepare_to_resume, x86_linux_process_qsupported, diff --git a/gdb/gdbserver/linux-xtensa-low.c b/gdb/gdbserver/linux-xtensa-low.c index 214abdc938b..5f2566cc0b0 100644 --- a/gdb/gdbserver/linux-xtensa-low.c +++ b/gdb/gdbserver/linux-xtensa-low.c @@ -289,6 +289,7 @@ struct linux_target_ops the_low_target = { NULL, /* siginfo_fixup */ NULL, /* new_process */ NULL, /* new_thread */ + NULL, /* delete_thread */ NULL, /* new_fork */ NULL, /* prepare_to_resume */ NULL, /* process_qsupported */ diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c index 60804159f1a..c89303c161f 100644 --- a/gdb/linux-nat.c +++ b/gdb/linux-nat.c @@ -197,6 +197,9 @@ static struct target_ops linux_ops_saved; /* The method to call, if any, when a new thread is attached. */ static void (*linux_nat_new_thread) (struct lwp_info *); +/* The method to call, if any, when a thread is destroyed. */ +static void (*linux_nat_delete_thread) (struct arch_lwp_info *); + /* The method to call, if any, when a new fork is attached. */ static linux_nat_new_fork_ftype *linux_nat_new_fork; @@ -839,7 +842,12 @@ static int check_ptrace_stopped_lwp_gone (struct lwp_info *lp); static void lwp_free (struct lwp_info *lp) { - xfree (lp->arch_private); + /* Let the arch specific bits release arch_lwp_info. */ + if (linux_nat_delete_thread != NULL) + linux_nat_delete_thread (lp->arch_private); + else + gdb_assert (lp->arch_private == NULL); + xfree (lp); } @@ -4873,6 +4881,17 @@ linux_nat_set_new_thread (struct target_ops *t, linux_nat_new_thread = new_thread; } +/* Register a method to call whenever a new thread is attached. */ +void +linux_nat_set_delete_thread (struct target_ops *t, + void (*delete_thread) (struct arch_lwp_info *)) +{ + /* Save the pointer. We only support a single registered instance + of the GNU/Linux native target, so we do not need to map this to + T. */ + linux_nat_delete_thread = delete_thread; +} + /* See declaration in linux-nat.h. */ void diff --git a/gdb/linux-nat.h b/gdb/linux-nat.h index 3378bd64017..c00267959d1 100644 --- a/gdb/linux-nat.h +++ b/gdb/linux-nat.h @@ -165,6 +165,9 @@ void linux_nat_add_target (struct target_ops *); /* Register a method to call whenever a new thread is attached. */ void linux_nat_set_new_thread (struct target_ops *, void (*) (struct lwp_info *)); +/* Register a method to call whenever a new thread is deleted. */ +void linux_nat_set_delete_thread (struct target_ops *, + void (*) (struct arch_lwp_info *)); /* Register a method to call whenever a new fork is attached. */ typedef void (linux_nat_new_fork_ftype) (struct lwp_info *parent, diff --git a/gdb/nat/aarch64-linux.c b/gdb/nat/aarch64-linux.c index 388eee8a6e4..d7abee8824b 100644 --- a/gdb/nat/aarch64-linux.c +++ b/gdb/nat/aarch64-linux.c @@ -84,6 +84,14 @@ aarch64_linux_new_thread (struct lwp_info *lwp) lwp_set_arch_private_info (lwp, info); } +/* See nat/aarch64-linux.h. */ + +void +aarch64_linux_delete_thread (struct arch_lwp_info *arch_lwp) +{ + xfree (arch_lwp); +} + /* Convert native siginfo FROM to the siginfo in the layout of the inferior's architecture TO. */ diff --git a/gdb/nat/aarch64-linux.h b/gdb/nat/aarch64-linux.h index 191e1c62ba5..db98df4725f 100644 --- a/gdb/nat/aarch64-linux.h +++ b/gdb/nat/aarch64-linux.h @@ -122,6 +122,9 @@ void aarch64_linux_prepare_to_resume (struct lwp_info *lwp); void aarch64_linux_new_thread (struct lwp_info *lwp); +/* Function to call when a thread is being deleted. */ +void aarch64_linux_delete_thread (struct arch_lwp_info *arch_lwp); + ps_err_e aarch64_ps_get_thread_area (struct ps_prochandle *ph, lwpid_t lwpid, int idx, void **base, int is_64bit_p); diff --git a/gdb/nat/x86-linux.c b/gdb/nat/x86-linux.c index b499e74e3ff..fc68106fe48 100644 --- a/gdb/nat/x86-linux.c +++ b/gdb/nat/x86-linux.c @@ -67,6 +67,14 @@ x86_linux_new_thread (struct lwp_info *lwp) /* See nat/x86-linux.h. */ +void +x86_linux_delete_thread (struct arch_lwp_info *arch_lwp) +{ + xfree (arch_lwp); +} + +/* See nat/x86-linux.h. */ + void x86_linux_prepare_to_resume (struct lwp_info *lwp) { diff --git a/gdb/nat/x86-linux.h b/gdb/nat/x86-linux.h index 1b7fee4263a..493c722d7f8 100644 --- a/gdb/nat/x86-linux.h +++ b/gdb/nat/x86-linux.h @@ -39,6 +39,10 @@ extern int lwp_debug_registers_changed (struct lwp_info *lwp); extern void x86_linux_new_thread (struct lwp_info *lwp); +/* Function to call when a thread is being deleted. */ + +extern void x86_linux_delete_thread (struct arch_lwp_info *arch_lwp); + /* Function to call prior to resuming a thread. */ extern void x86_linux_prepare_to_resume (struct lwp_info *lwp); diff --git a/gdb/s390-linux-nat.c b/gdb/s390-linux-nat.c index 4d1b8b54ae5..88ae5750908 100644 --- a/gdb/s390-linux-nat.c +++ b/gdb/s390-linux-nat.c @@ -789,6 +789,14 @@ s390_new_thread (struct lwp_info *lp) s390_mark_per_info_changed (lp); } +/* Function to call when a thread is being deleted. */ + +static void +s390_delete_thread (struct arch_lwp_info *arch_lwp) +{ + xfree (arch_lwp); +} + /* Iterator callback for s390_refresh_per_info. */ static int @@ -1050,6 +1058,7 @@ _initialize_s390_nat (void) /* Register the target. */ linux_nat_add_target (t); linux_nat_set_new_thread (t, s390_new_thread); + linux_nat_set_delete_thread (t, s390_delete_thread); linux_nat_set_prepare_to_resume (t, s390_prepare_to_resume); linux_nat_set_forget_process (t, s390_forget_process); linux_nat_set_new_fork (t, s390_linux_new_fork); diff --git a/gdb/x86-linux-nat.c b/gdb/x86-linux-nat.c index 46115270581..ce56c2e6521 100644 --- a/gdb/x86-linux-nat.c +++ b/gdb/x86-linux-nat.c @@ -354,6 +354,7 @@ x86_linux_add_target (struct target_ops *t) { linux_nat_add_target (t); linux_nat_set_new_thread (t, x86_linux_new_thread); + linux_nat_set_delete_thread (t, x86_linux_delete_thread); linux_nat_set_new_fork (t, x86_linux_new_fork); linux_nat_set_forget_process (t, x86_forget_process); linux_nat_set_prepare_to_resume (t, x86_linux_prepare_to_resume);