This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
Re: [RFA] thread.c: plug leaks, zero thread count
- To: Nick Duffek <nsd at redhat dot com>
- Subject: Re: [RFA] thread.c: plug leaks, zero thread count
- From: Michael Snyder <msnyder at cygnus dot com>
- Date: Wed, 19 Jul 2000 13:45:29 -0700
- CC: gdb-patches at sourceware dot cygnus dot com
- Organization: Cygnus Solutions
- References: <200007192042.QAA09598@nog.bosbc.com>
Good. Please apply.
Nick Duffek wrote:
>
> Plug leaks
> ----------
>
> delete_thread() does this to each thread it deletes:
>
> if (tp->step_resume_breakpoint)
> delete_breakpoint (tp->step_resume_breakpoint);
> if (tp->private)
> free (tp->private);
> free (tp);
>
> But init_thread_list() only does this to each thread it deletes:
>
> free (tp);
>
> So, it leaks memory and breakpoints. The attached patch fixes that by
> moving delete_thread's cleanup code into a new function, free_thread(),
> and then calling that in delete_thread() and init_thread_list().
>
> Zero thread count
> -----------------
>
> If GDB notices all thread exit events, then when an inferior exits,
> thread_list will be empty but highest_thread_num may be > 0, causing the
> next run to start numbering threads at > 1.
>
> The attached patch sets highest_thread_num to 0 before rather than after
> checking for a NULL thread_list.
>
> Okay to apply?
>
> Nick Duffek
> nsd@redhat.com
>
> 2000-07-19 Nicholas Duffek <nsd@redhat.com>
>
> * thread.c (free_thread): New function.
> (init_thread_list): Always zero highest_thread_num. Call
> free_thread() instead of free().
> (delete_thread): Move thread cleanup code to free_thread().
>
> Index: gdb/thread.c
> ===================================================================
> diff -up gdb/thread.c gdb/thread.c
> --- gdb/thread.c Wed Jul 19 15:22:40 2000
> +++ gdb/thread.c Wed Jul 19 15:22:08 2000
> @@ -63,22 +63,38 @@ static void restore_current_thread (int)
> static void switch_to_thread (int pid);
> static void prune_threads (void);
>
> +static void
> +free_thread (struct thread_info *tp)
> +{
> + /* NOTE: this will take care of any left-over step_resume breakpoints,
> + but not any user-specified thread-specific breakpoints. */
> + if (tp->step_resume_breakpoint)
> + delete_breakpoint (tp->step_resume_breakpoint);
> +
> + /* FIXME: do I ever need to call the back-end to give it a
> + chance at this private data before deleting the thread? */
> + if (tp->private)
> + free (tp->private);
> +
> + free (tp);
> +}
> +
> void
> init_thread_list ()
> {
> struct thread_info *tp, *tpnext;
>
> + highest_thread_num = 0;
> if (!thread_list)
> return;
>
> for (tp = thread_list; tp; tp = tpnext)
> {
> tpnext = tp->next;
> - free (tp);
> + free_thread (tp);
> }
>
> thread_list = NULL;
> - highest_thread_num = 0;
> }
>
> /* add_thread now returns a pointer to the new thread_info,
> @@ -134,19 +150,7 @@ delete_thread (pid)
> else
> thread_list = tp->next;
>
> - /* NOTE: this will take care of any left-over step_resume breakpoints,
> - but not any user-specified thread-specific breakpoints. */
> - if (tp->step_resume_breakpoint)
> - delete_breakpoint (tp->step_resume_breakpoint);
> -
> - /* FIXME: do I ever need to call the back-end to give it a
> - chance at this private data before deleting the thread? */
> - if (tp->private)
> - free (tp->private);
> -
> - free (tp);
> -
> - return;
> + free_thread (tp);
> }
>
> static struct thread_info *