/* Thread management interface, for the remote server for GDB.
   Copyright (C) 2002-2025 Free Software Foundation, Inc.

   Contributed by MontaVista Software.

   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/>.  */


#include "linux-low.h"

#include "debug.h"
#include "gdb_proc_service.h"
#include "nat/gdb_thread_db.h"
#include "gdbsupport/gdb_vecs.h"
#include "nat/linux-procfs.h"
#include "gdbsupport/scoped_restore.h"

#ifndef USE_LIBTHREAD_DB_DIRECTLY
#include <dlfcn.h>
#endif
#include <limits.h>

struct thread_db
{
  /* Structure that identifies the child process for the
     <proc_service.h> interface.  */
  struct ps_prochandle proc_handle;

  /* Connection to the libthread_db library.  */
  td_thragent_t *thread_agent;

  /* If this flag has been set, we've already asked GDB for all
     symbols we might need; assume symbol cache misses are
     failures.  */
  int all_symbols_looked_up;

#ifndef USE_LIBTHREAD_DB_DIRECTLY
  /* Handle of the libthread_db from dlopen.  */
  void *handle;
#endif

  /* Addresses of libthread_db functions.  */
  td_ta_new_ftype *td_ta_new_p;
  td_ta_map_lwp2thr_ftype *td_ta_map_lwp2thr_p;
  td_thr_get_info_ftype *td_thr_get_info_p;
  td_ta_thr_iter_ftype *td_ta_thr_iter_p;
  td_thr_tls_get_addr_ftype *td_thr_tls_get_addr_p;
  td_thr_tlsbase_ftype *td_thr_tlsbase_p;
  td_symbol_list_ftype *td_symbol_list_p;
};

static char *libthread_db_search_path;

static int find_one_thread (ptid_t);
static int find_new_threads_callback (const td_thrhandle_t *th_p, void *data);

static const char *
thread_db_err_str (td_err_e err)
{
  static char buf[64];

  switch (err)
    {
    case TD_OK:
      return "generic 'call succeeded'";
    case TD_ERR:
      return "generic error";
    case TD_NOTHR:
      return "no thread to satisfy query";
    case TD_NOSV:
      return "no sync handle to satisfy query";
    case TD_NOLWP:
      return "no LWP to satisfy query";
    case TD_BADPH:
      return "invalid process handle";
    case TD_BADTH:
      return "invalid thread handle";
    case TD_BADSH:
      return "invalid synchronization handle";
    case TD_BADTA:
      return "invalid thread agent";
    case TD_BADKEY:
      return "invalid key";
    case TD_NOMSG:
      return "no event message for getmsg";
    case TD_NOFPREGS:
      return "FPU register set not available";
    case TD_NOLIBTHREAD:
      return "application not linked with libthread";
    case TD_NOEVENT:
      return "requested event is not supported";
    case TD_NOCAPAB:
      return "capability not available";
    case TD_DBERR:
      return "debugger service failed";
    case TD_NOAPLIC:
      return "operation not applicable to";
    case TD_NOTSD:
      return "no thread-specific data for this thread";
    case TD_MALLOC:
      return "malloc failed";
    case TD_PARTIALREG:
      return "only part of register set was written/read";
    case TD_NOXREGS:
      return "X register set not available for this thread";
#ifdef HAVE_TD_VERSION
    case TD_VERSION:
      return "version mismatch between libthread_db and libpthread";
#endif
    default:
      xsnprintf (buf, sizeof (buf), "unknown thread_db error '%d'", err);
      return buf;
    }
}

#if 0
static char *
thread_db_state_str (td_thr_state_e state)
{
  static char buf[64];

  switch (state)
    {
    case TD_THR_STOPPED:
      return "stopped by debugger";
    case TD_THR_RUN:
      return "runnable";
    case TD_THR_ACTIVE:
      return "active";
    case TD_THR_ZOMBIE:
      return "zombie";
    case TD_THR_SLEEP:
      return "sleeping";
    case TD_THR_STOPPED_ASLEEP:
      return "stopped by debugger AND blocked";
    default:
      xsnprintf (buf, sizeof (buf), "unknown thread_db state %d", state);
      return buf;
    }
}
#endif

/* Get thread info about PTID.  */

static int
find_one_thread (ptid_t ptid)
{
  thread_info *thread = find_thread_ptid (ptid);
  lwp_info *lwp = get_thread_lwp (thread);
  if (lwp->thread_known)
    return 1;

  /* Get information about this thread.  libthread_db will need to read some
     memory, which will be done on the current process, so make PTID's process
     the current one.  */
  process_info *proc = find_process_pid (ptid.pid ());
  gdb_assert (proc != nullptr);

  scoped_restore_current_thread restore_thread;
  switch_to_process (proc);

  thread_db *thread_db = proc->priv->thread_db;
  td_thrhandle_t th;
  int lwpid = ptid.lwp ();
  td_err_e err = thread_db->td_ta_map_lwp2thr_p (thread_db->thread_agent, lwpid,
						 &th);
  if (err != TD_OK)
    error ("Cannot get thread handle for LWP %d: %s",
	   lwpid, thread_db_err_str (err));

  td_thrinfo_t ti;
  err = thread_db->td_thr_get_info_p (&th, &ti);
  if (err != TD_OK)
    error ("Cannot get thread info for LWP %d: %s",
	   lwpid, thread_db_err_str (err));

  threads_debug_printf ("Found thread %ld (LWP %d)",
			(unsigned long) ti.ti_tid, ti.ti_lid);

  if (lwpid != ti.ti_lid)
    {
      warning ("PID mismatch!  Expected %ld, got %ld",
	       (long) lwpid, (long) ti.ti_lid);
      return 0;
    }

  /* If the new thread ID is zero, a final thread ID will be available
     later.  Do not enable thread debugging yet.  */
  if (ti.ti_tid == 0)
    return 0;

  lwp->thread_known = 1;
  lwp->th = th;
  lwp->thread_handle = ti.ti_tid;

  return 1;
}

/* Attach a thread.  Return true on success.  */

static int
attach_thread (const td_thrhandle_t *th_p, td_thrinfo_t *ti_p)
{
  struct process_info *proc = current_process ();
  int pid = proc->pid;
  ptid_t ptid = ptid_t (pid, ti_p->ti_lid);
  struct lwp_info *lwp;
  int err;

  threads_debug_printf ("Attaching to thread %ld (LWP %d)",
			(unsigned long) ti_p->ti_tid, ti_p->ti_lid);
  err = the_linux_target->attach_lwp (ptid);
  if (err != 0)
    {
      std::string reason = linux_ptrace_attach_fail_reason_string (ptid, err);

      warning ("Could not attach to thread %ld (LWP %d): %s",
	       (unsigned long) ti_p->ti_tid, ti_p->ti_lid, reason.c_str ());

      return 0;
    }

  lwp = find_lwp_pid (ptid);
  gdb_assert (lwp != NULL);
  lwp->thread_known = 1;
  lwp->th = *th_p;
  lwp->thread_handle = ti_p->ti_tid;

  return 1;
}

/* Attach thread if we haven't seen it yet.
   Increment *COUNTER if we have attached a new thread.
   Return false on failure.  */

static int
maybe_attach_thread (const td_thrhandle_t *th_p, td_thrinfo_t *ti_p,
		     int *counter)
{
  struct lwp_info *lwp;

  lwp = find_lwp_pid (ptid_t (ti_p->ti_lid));
  if (lwp != NULL)
    return 1;

  if (!attach_thread (th_p, ti_p))
    return 0;

  if (counter != NULL)
    *counter += 1;

  return 1;
}

static int
find_new_threads_callback (const td_thrhandle_t *th_p, void *data)
{
  td_thrinfo_t ti;
  td_err_e err;
  struct thread_db *thread_db = current_process ()->priv->thread_db;

  err = thread_db->td_thr_get_info_p (th_p, &ti);
  if (err != TD_OK)
    error ("Cannot get thread info: %s", thread_db_err_str (err));

  if (ti.ti_lid == -1)
    {
      /* A thread with kernel thread ID -1 is either a thread that
	 exited and was joined, or a thread that is being created but
	 hasn't started yet, and that is reusing the tcb/stack of a
	 thread that previously exited and was joined.  (glibc marks
	 terminated and joined threads with kernel thread ID -1.  See
	 glibc PR17707.  */
      threads_debug_printf ("thread_db: skipping exited and "
			    "joined thread (0x%lx)",
			    (unsigned long) ti.ti_tid);
      return 0;
    }

  /* Check for zombies.  */
  if (ti.ti_state == TD_THR_UNKNOWN || ti.ti_state == TD_THR_ZOMBIE)
    return 0;

  if (!maybe_attach_thread (th_p, &ti, (int *) data))
    {
      /* Terminate iteration early: we might be looking at stale data in
	 the inferior.  The thread_db_find_new_threads will retry.  */
      return 1;
    }

  return 0;
}

static void
thread_db_find_new_threads (void)
{
  td_err_e err;
  ptid_t ptid = current_thread->id;
  struct thread_db *thread_db = current_process ()->priv->thread_db;
  int loop, iteration;

  /* This function is only called when we first initialize thread_db.
     First locate the initial thread.  If it is not ready for
     debugging yet, then stop.  */
  if (find_one_thread (ptid) == 0)
    return;

  /* Require 4 successive iterations which do not find any new threads.
     The 4 is a heuristic: there is an inherent race here, and I have
     seen that 2 iterations in a row are not always sufficient to
     "capture" all threads.  */
  for (loop = 0, iteration = 0; loop < 4; ++loop, ++iteration)
    {
      int new_thread_count = 0;

      /* Iterate over all user-space threads to discover new threads.  */
      err = thread_db->td_ta_thr_iter_p (thread_db->thread_agent,
					 find_new_threads_callback,
					 &new_thread_count,
					 TD_THR_ANY_STATE,
					 TD_THR_LOWEST_PRIORITY,
					 TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
      threads_debug_printf ("Found %d threads in iteration %d.",
			    new_thread_count, iteration);

      if (new_thread_count != 0)
	{
	  /* Found new threads.  Restart iteration from beginning.  */
	  loop = -1;
	}
    }
  if (err != TD_OK)
    error ("Cannot find new threads: %s", thread_db_err_str (err));
}

/* Cache all future symbols that thread_db might request.  We can not
   request symbols at arbitrary states in the remote protocol, only
   when the client tells us that new symbols are available.  So when
   we load the thread library, make sure to check the entire list.  */

static void
thread_db_look_up_symbols (void)
{
  struct thread_db *thread_db = current_process ()->priv->thread_db;
  const char **sym_list;
  CORE_ADDR unused;

  for (sym_list = thread_db->td_symbol_list_p (); *sym_list; sym_list++)
    look_up_one_symbol (*sym_list, &unused, 1);

  /* We're not interested in any other libraries loaded after this
     point, only in symbols in libpthread.so.  */
  thread_db->all_symbols_looked_up = 1;
}

int
thread_db_look_up_one_symbol (const char *name, CORE_ADDR *addrp)
{
  struct thread_db *thread_db = current_process ()->priv->thread_db;
  int may_ask_gdb = !thread_db->all_symbols_looked_up;

  /* If we've passed the call to thread_db_look_up_symbols, then
     anything not in the cache must not exist; we're not interested
     in any libraries loaded after that point, only in symbols in
     libpthread.so.  It might not be an appropriate time to look
     up a symbol, e.g. while we're trying to fetch registers.  */
  return look_up_one_symbol (name, addrp, may_ask_gdb);
}

int
thread_db_get_tls_address (thread_info *thread, CORE_ADDR offset,
			   CORE_ADDR load_module, CORE_ADDR *address)
{
  psaddr_t addr;
  td_err_e err;
  struct lwp_info *lwp;
  struct thread_db *thread_db;
  process_info *proc = thread->process ();

  thread_db = proc->priv->thread_db;

  /* If the thread layer is not (yet) initialized, fail.  */
  if (thread_db == NULL || !thread_db->all_symbols_looked_up)
    return TD_ERR;

  /* If td_thr_tls_get_addr is missing rather do not expect td_thr_tlsbase
     could work.  */
  if (thread_db->td_thr_tls_get_addr_p == NULL
      || (load_module == 0 && thread_db->td_thr_tlsbase_p == NULL))
    return -1;

  lwp = get_thread_lwp (thread);
  if (!lwp->thread_known)
    find_one_thread (thread->id);
  if (!lwp->thread_known)
    return TD_NOTHR;

  scoped_restore_current_thread restore_thread;
  switch_to_thread (thread);

  if (load_module != 0)
    {
      /* Note the cast through uintptr_t: this interface only works if
	 a target address fits in a psaddr_t, which is a host pointer.
	 So a 32-bit debugger can not access 64-bit TLS through this.  */
      err = thread_db->td_thr_tls_get_addr_p (&lwp->th,
					     (psaddr_t) (uintptr_t) load_module,
					      offset, &addr);
    }
  else
    {
      /* This code path handles the case of -static -pthread executables:
	 https://sourceware.org/ml/libc-help/2014-03/msg00024.html
	 For older GNU libc r_debug.r_map is NULL.  For GNU libc after
	 PR libc/16831 due to GDB PR threads/16954 LOAD_MODULE is also NULL.
	 The constant number 1 depends on GNU __libc_setup_tls
	 initialization of l_tls_modid to 1.  */
      err = thread_db->td_thr_tlsbase_p (&lwp->th, 1, &addr);
      addr = (char *) addr + offset;
    }

  if (err == TD_OK)
    {
      *address = (CORE_ADDR) (uintptr_t) addr;
      return 0;
    }
  else
    return err;
}

/* See linux-low.h.  */

bool
thread_db_thread_handle (ptid_t ptid, gdb_byte **handle, int *handle_len)
{
  struct lwp_info *lwp;
  thread_info *thread = find_thread_ptid (ptid);

  if (thread == NULL)
    return false;

  thread_db *thread_db = thread->process ()->priv->thread_db;

  if (thread_db == NULL)
    return false;

  lwp = get_thread_lwp (thread);

  if (!lwp->thread_known && !find_one_thread (thread->id))
    return false;

  gdb_assert (lwp->thread_known);

  *handle = (gdb_byte *) &lwp->thread_handle;
  *handle_len = sizeof (lwp->thread_handle);
  return true;
}

#ifdef USE_LIBTHREAD_DB_DIRECTLY

static int
thread_db_load_search (void)
{
  td_err_e err;
  struct thread_db *tdb;
  struct process_info *proc = current_process ();

  gdb_assert (proc->priv->thread_db == NULL);

  tdb = XCNEW (struct thread_db);
  proc->priv->thread_db = tdb;

  tdb->td_ta_new_p = &td_ta_new;

  /* Attempt to open a connection to the thread library.  */
  err = tdb->td_ta_new_p (&tdb->proc_handle, &tdb->thread_agent);
  if (err != TD_OK)
    {
      threads_debug_printf ("td_ta_new(): %s", thread_db_err_str (err));
      free (tdb);
      proc->priv->thread_db = NULL;
      return 0;
    }

  tdb->td_ta_map_lwp2thr_p = &td_ta_map_lwp2thr;
  tdb->td_thr_get_info_p = &td_thr_get_info;
  tdb->td_ta_thr_iter_p = &td_ta_thr_iter;
  tdb->td_symbol_list_p = &td_symbol_list;

  /* These are not essential.  */
  tdb->td_thr_tls_get_addr_p = &td_thr_tls_get_addr;
  tdb->td_thr_tlsbase_p = &td_thr_tlsbase;

  return 1;
}

#else

static int
try_thread_db_load_1 (void *handle)
{
  td_err_e err;
  struct thread_db *tdb;
  struct process_info *proc = current_process ();

  gdb_assert (proc->priv->thread_db == NULL);

  tdb = XCNEW (struct thread_db);
  proc->priv->thread_db = tdb;

  tdb->handle = handle;

  /* Initialize pointers to the dynamic library functions we will use.
     Essential functions first.  */

#define CHK(required, a)					\
  do								\
    {								\
      if ((a) == NULL)						\
	{							\
	  threads_debug_printf ("dlsym: %s", dlerror ());	\
	  if (required)						\
	    {							\
	      free (tdb);					\
	      proc->priv->thread_db = NULL;			\
	      return 0;						\
	    }							\
	}							\
    }								\
  while (0)

#define TDB_DLSYM(tdb, func) \
  tdb->func ## _p = (func ## _ftype *) dlsym (tdb->handle, #func)

  CHK (1, TDB_DLSYM (tdb, td_ta_new));

  /* Attempt to open a connection to the thread library.  */
  err = tdb->td_ta_new_p (&tdb->proc_handle, &tdb->thread_agent);
  if (err != TD_OK)
    {
      threads_debug_printf ("td_ta_new(): %s", thread_db_err_str (err));
      free (tdb);
      proc->priv->thread_db = NULL;
      return 0;
    }

  CHK (1, TDB_DLSYM (tdb, td_ta_map_lwp2thr));
  CHK (1, TDB_DLSYM (tdb, td_thr_get_info));
  CHK (1, TDB_DLSYM (tdb, td_ta_thr_iter));
  CHK (1, TDB_DLSYM (tdb, td_symbol_list));

  /* These are not essential.  */
  CHK (0, TDB_DLSYM (tdb, td_thr_tls_get_addr));
  CHK (0, TDB_DLSYM (tdb, td_thr_tlsbase));

#undef CHK
#undef TDB_DLSYM

  return 1;
}

#ifdef HAVE_DLADDR

/* Lookup a library in which given symbol resides.
   Note: this is looking in the GDBSERVER process, not in the inferior.
   Returns library name, or NULL.  */

static const char *
dladdr_to_soname (const void *addr)
{
  Dl_info info;

  if (dladdr (addr, &info) != 0)
    return info.dli_fname;
  return NULL;
}

#endif

static int
try_thread_db_load (const char *library)
{
  void *handle;

  threads_debug_printf ("Trying host libthread_db library: %s.",
			library);
  handle = dlopen (library, RTLD_NOW);
  if (handle == NULL)
    {
      threads_debug_printf ("dlopen failed: %s.", dlerror ());
      return 0;
    }

#ifdef HAVE_DLADDR
  if (debug_threads && strchr (library, '/') == NULL)
    {
      void *td_init;

      td_init = dlsym (handle, "td_init");
      if (td_init != NULL)
	{
	  const char *const libpath = dladdr_to_soname (td_init);

	  if (libpath != NULL)
	    threads_debug_printf ("Host %s resolved to: %s.", library, libpath);
	}
    }
#endif

  if (try_thread_db_load_1 (handle))
    return 1;

  /* This library "refused" to work on current inferior.  */
  dlclose (handle);
  return 0;
}

/* Handle $sdir in libthread-db-search-path.
   Look for libthread_db in the system dirs, or wherever a plain
   dlopen(file_without_path) will look.
   The result is true for success.  */

static int
try_thread_db_load_from_sdir (void)
{
  return try_thread_db_load (LIBTHREAD_DB_SO);
}

/* Try to load libthread_db from directory DIR of length DIR_LEN.
   The result is true for success.  */

static int
try_thread_db_load_from_dir (const char *dir, size_t dir_len)
{
  char path[PATH_MAX];

  if (dir_len + 1 + strlen (LIBTHREAD_DB_SO) + 1 > sizeof (path))
    {
      char *cp = (char *) xmalloc (dir_len + 1);

      memcpy (cp, dir, dir_len);
      cp[dir_len] = '\0';
      warning (_("libthread-db-search-path component too long,"
		 " ignored: %s."), cp);
      free (cp);
      return 0;
    }

  memcpy (path, dir, dir_len);
  path[dir_len] = '/';
  strcpy (path + dir_len + 1, LIBTHREAD_DB_SO);
  return try_thread_db_load (path);
}

/* Search libthread_db_search_path for libthread_db which "agrees"
   to work on current inferior.
   The result is true for success.  */

static int
thread_db_load_search (void)
{
  int rc = 0;

  if (libthread_db_search_path == NULL)
    libthread_db_search_path = xstrdup (LIBTHREAD_DB_SEARCH_PATH);

  std::vector<gdb::unique_xmalloc_ptr<char>> dir_vec
    = dirnames_to_char_ptr_vec (libthread_db_search_path);

  for (const gdb::unique_xmalloc_ptr<char> &this_dir_up : dir_vec)
    {
      char *this_dir = this_dir_up.get ();
      const int pdir_len = sizeof ("$pdir") - 1;
      size_t this_dir_len;

      this_dir_len = strlen (this_dir);

      if (strncmp (this_dir, "$pdir", pdir_len) == 0
	  && (this_dir[pdir_len] == '\0'
	      || this_dir[pdir_len] == '/'))
	{
	  /* We don't maintain a list of loaded libraries so we don't know
	     where libpthread lives.  We *could* fetch the info, but we don't
	     do that yet.  Ignore it.  */
	}
      else if (strcmp (this_dir, "$sdir") == 0)
	{
	  if (try_thread_db_load_from_sdir ())
	    {
	      rc = 1;
	      break;
	    }
	}
      else
	{
	  if (try_thread_db_load_from_dir (this_dir, this_dir_len))
	    {
	      rc = 1;
	      break;
	    }
	}
    }

  threads_debug_printf ("thread_db_load_search returning %d", rc);
  return rc;
}

#endif  /* USE_LIBTHREAD_DB_DIRECTLY */

int
thread_db_init (void)
{
  struct process_info *proc = current_process ();

  /* FIXME drow/2004-10-16: This is the "overall process ID", which
     GNU/Linux calls tgid, "thread group ID".  When we support
     attaching to threads, the original thread may not be the correct
     thread.  We would have to get the process ID from /proc for NPTL.

     This isn't the only place in gdbserver that assumes that the first
     process in the list is the thread group leader.  */

  if (thread_db_load_search ())
    {
      /* It's best to avoid td_ta_thr_iter if possible.  That walks
	 data structures in the inferior's address space that may be
	 corrupted, or, if the target is running, the list may change
	 while we walk it.  In the latter case, it's possible that a
	 thread exits just at the exact time that causes GDBserver to
	 get stuck in an infinite loop.  As the kernel supports clone
	 events and /proc/PID/task/ exists, then we already know about
	 all threads in the process.  When we need info out of
	 thread_db on a given thread (e.g., for TLS), we'll use
	 find_one_thread then.  That uses thread_db entry points that
	 do not walk libpthread's thread list, so should be safe, as
	 well as more efficient.  */
      if (!linux_proc_task_list_dir_exists (proc->pid))
	thread_db_find_new_threads ();
      thread_db_look_up_symbols ();
      return 1;
    }

  return 0;
}

/* Disconnect from libthread_db and free resources.  */

static void
disable_thread_event_reporting (struct process_info *proc)
{
  struct thread_db *thread_db = proc->priv->thread_db;
  if (thread_db)
    {
      td_err_e (*td_ta_clear_event_p) (const td_thragent_t *ta,
				       td_thr_events_t *event);

#ifndef USE_LIBTHREAD_DB_DIRECTLY
      td_ta_clear_event_p
	= (td_ta_clear_event_ftype *) dlsym (thread_db->handle,
					     "td_ta_clear_event");
#else
      td_ta_clear_event_p = &td_ta_clear_event;
#endif

      if (td_ta_clear_event_p != NULL)
	{
	  scoped_restore_current_thread restore_thread;
	  td_thr_events_t events;

	  switch_to_process (proc);

	  /* Set the process wide mask saying we aren't interested
	     in any events anymore.  */
	  td_event_fillset (&events);
	  (*td_ta_clear_event_p) (thread_db->thread_agent, &events);
	}
    }
}

void
thread_db_detach (struct process_info *proc)
{
  struct thread_db *thread_db = proc->priv->thread_db;

  if (thread_db)
    {
      disable_thread_event_reporting (proc);
    }
}

/* Disconnect from libthread_db and free resources.  */

void
thread_db_mourn (struct process_info *proc)
{
  struct thread_db *thread_db = proc->priv->thread_db;
  if (thread_db)
    {
      td_ta_delete_ftype *td_ta_delete_p;

#ifndef USE_LIBTHREAD_DB_DIRECTLY
      td_ta_delete_p = (td_ta_delete_ftype *) dlsym (thread_db->handle, "td_ta_delete");
#else
      td_ta_delete_p = &td_ta_delete;
#endif

      if (td_ta_delete_p != NULL)
	(*td_ta_delete_p) (thread_db->thread_agent);

#ifndef USE_LIBTHREAD_DB_DIRECTLY
      dlclose (thread_db->handle);
#endif  /* USE_LIBTHREAD_DB_DIRECTLY  */

      free (thread_db);
      proc->priv->thread_db = NULL;
    }
}

/* Handle "set libthread-db-search-path" monitor command and return 1.
   For any other command, return 0.  */

int
thread_db_handle_monitor_command (char *mon)
{
  const char *cmd = "set libthread-db-search-path";
  size_t cmd_len = strlen (cmd);

  if (strncmp (mon, cmd, cmd_len) == 0
      && (mon[cmd_len] == '\0'
	  || mon[cmd_len] == ' '))
    {
      const char *cp = mon + cmd_len;

      if (libthread_db_search_path != NULL)
	free (libthread_db_search_path);

      /* Skip leading space (if any).  */
      while (c_isspace (*cp))
	++cp;

      if (*cp == '\0')
	cp = LIBTHREAD_DB_SEARCH_PATH;
      libthread_db_search_path = xstrdup (cp);

      monitor_output ("libthread-db-search-path set to `");
      monitor_output (libthread_db_search_path);
      monitor_output ("'\n");
      return 1;
    }

  /* Tell server.c to perform default processing.  */
  return 0;
}

/* See linux-low.h.  */

void
thread_db_notice_clone (thread_info *parent_thr, ptid_t child_ptid)
{
  thread_db *thread_db = parent_thr->process ()->priv->thread_db;

  /* If the thread layer isn't initialized, return.  It may just
     be that the program uses clone, but does not use libthread_db.  */
  if (thread_db == NULL || !thread_db->all_symbols_looked_up)
    return;

  /* find_one_thread calls into libthread_db which accesses memory via
     the current thread.  Temporarily switch to a thread we know is
     stopped.  */
  scoped_restore_current_thread restore_thread;
  switch_to_thread (parent_thr);

  if (!find_one_thread (child_ptid))
    warning ("Cannot find thread after clone.");
}
