/* 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>
#include <ctype.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 (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.");
}
