Support $pdir and $sdir in libthread-db-search-path.
* NEWS: Mention $sdir,$pdir. * gdb_thread_db.h (LIBTHREAD_DB_SEARCH_PATH): Add $sdir:$pdir. * linux-thread-db.c (try_thread_db_load_from_pdir): New function. (try_thread_db_load_from_sdir): New function. (try_thread_db_load_from_dir): New function. (thread_db_load_search): Handle $pdir, $sdir. Remove trying of system directories if search of libthread-db-search-path fails, that is now done via $sdir. (has_libpthread): New function. (thread_db_load): Remove search for libthread_db in directory of libpthread, that is now done via $pdir. gdbserver/ * thread-db.c (try_thread_db_load_from_sdir): New function. (try_thread_db_load_from_dir): New function. (thread_db_load_search): Handle $sdir, ignore $pdir. Remove trying of system directories if search of libthread-db-search-path fails, that is now done via $sdir. doc/ * gdb.texinfo (Threads): Document $sdir,$pdir. (Server): Document $pdir exception.
This commit is contained in:
parent
dbaefcf757
commit
98a5dd1327
8 changed files with 275 additions and 123 deletions
|
@ -812,95 +812,14 @@ try_thread_db_load (const char *library)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Search libthread_db_search_path for libthread_db which "agrees"
|
||||
to work on current inferior. */
|
||||
/* Handle $pdir in libthread-db-search-path.
|
||||
Look for libthread_db in the directory of libpthread.
|
||||
The result is true for success. */
|
||||
|
||||
static int
|
||||
thread_db_load_search (void)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
const char *search_path = libthread_db_search_path;
|
||||
int rc = 0;
|
||||
|
||||
while (*search_path)
|
||||
{
|
||||
const char *end = strchr (search_path, ':');
|
||||
|
||||
if (end)
|
||||
{
|
||||
size_t len = end - search_path;
|
||||
|
||||
if (len + 1 + strlen (LIBTHREAD_DB_SO) + 1 > sizeof (path))
|
||||
{
|
||||
char *cp = xmalloc (len + 1);
|
||||
|
||||
memcpy (cp, search_path, len);
|
||||
cp[len] = '\0';
|
||||
warning (_("libthread_db_search_path component too long,"
|
||||
" ignored: %s."), cp);
|
||||
xfree (cp);
|
||||
search_path += len + 1;
|
||||
continue;
|
||||
}
|
||||
memcpy (path, search_path, len);
|
||||
path[len] = '\0';
|
||||
search_path += len + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t len = strlen (search_path);
|
||||
|
||||
if (len + 1 + strlen (LIBTHREAD_DB_SO) + 1 > sizeof (path))
|
||||
{
|
||||
warning (_("libthread_db_search_path component too long,"
|
||||
" ignored: %s."), search_path);
|
||||
break;
|
||||
}
|
||||
memcpy (path, search_path, len + 1);
|
||||
search_path += len;
|
||||
}
|
||||
strcat (path, "/");
|
||||
strcat (path, LIBTHREAD_DB_SO);
|
||||
if (try_thread_db_load (path))
|
||||
{
|
||||
rc = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (rc == 0)
|
||||
rc = try_thread_db_load (LIBTHREAD_DB_SO);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Attempt to load and initialize libthread_db.
|
||||
Return 1 on success. */
|
||||
|
||||
static int
|
||||
thread_db_load (void)
|
||||
try_thread_db_load_from_pdir (void)
|
||||
{
|
||||
struct objfile *obj;
|
||||
struct thread_db_info *info;
|
||||
|
||||
info = get_thread_db_info (GET_PID (inferior_ptid));
|
||||
|
||||
if (info != NULL)
|
||||
return 1;
|
||||
|
||||
/* Don't attempt to use thread_db on executables not running
|
||||
yet. */
|
||||
if (!target_has_registers)
|
||||
return 0;
|
||||
|
||||
/* Don't attempt to use thread_db for remote targets. */
|
||||
if (!(target_can_run (¤t_target) || core_bfd))
|
||||
return 0;
|
||||
|
||||
if (thread_db_load_search ())
|
||||
return 1;
|
||||
|
||||
/* None of the libthread_db's on our search path, not the system default
|
||||
ones worked. If the executable is dynamically linked against
|
||||
libpthread, try loading libthread_db from the same directory. */
|
||||
|
||||
ALL_OBJFILES (obj)
|
||||
if (libpthread_name_p (obj->name))
|
||||
|
@ -927,10 +846,157 @@ thread_db_load (void)
|
|||
if (try_thread_db_load (path))
|
||||
return 1;
|
||||
}
|
||||
warning (_("Unable to find libthread_db matching inferior's thread"
|
||||
" library, thread debugging will not be available."));
|
||||
return 0;
|
||||
}
|
||||
|
||||
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 = xmalloc (dir_len + 1);
|
||||
|
||||
memcpy (cp, dir, dir_len);
|
||||
cp[dir_len] = '\0';
|
||||
warning (_("libthread-db-search-path component too long,"
|
||||
" ignored: %s."), cp);
|
||||
xfree (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)
|
||||
{
|
||||
const char *search_path = libthread_db_search_path;
|
||||
int rc = 0;
|
||||
|
||||
while (*search_path)
|
||||
{
|
||||
const char *end = strchr (search_path, ':');
|
||||
const char *this_dir = search_path;
|
||||
size_t this_dir_len;
|
||||
|
||||
if (end)
|
||||
{
|
||||
this_dir_len = end - search_path;
|
||||
search_path += this_dir_len + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
this_dir_len = strlen (this_dir);
|
||||
search_path += this_dir_len;
|
||||
}
|
||||
|
||||
if (this_dir_len == sizeof ("$pdir") - 1
|
||||
&& strncmp (this_dir, "$pdir", this_dir_len) == 0)
|
||||
{
|
||||
if (try_thread_db_load_from_pdir ())
|
||||
{
|
||||
rc = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (this_dir_len == sizeof ("$sdir") - 1
|
||||
&& strncmp (this_dir, "$sdir", this_dir_len) == 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (libthread_db_debug)
|
||||
printf_unfiltered (_("thread_db_load_search returning %d\n"), rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Return non-zero if the inferior has a libpthread. */
|
||||
|
||||
static int
|
||||
has_libpthread (void)
|
||||
{
|
||||
struct objfile *obj;
|
||||
|
||||
ALL_OBJFILES (obj)
|
||||
if (libpthread_name_p (obj->name))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Attempt to load and initialize libthread_db.
|
||||
Return 1 on success. */
|
||||
|
||||
static int
|
||||
thread_db_load (void)
|
||||
{
|
||||
struct thread_db_info *info;
|
||||
|
||||
info = get_thread_db_info (GET_PID (inferior_ptid));
|
||||
|
||||
if (info != NULL)
|
||||
return 1;
|
||||
|
||||
/* Don't attempt to use thread_db on executables not running
|
||||
yet. */
|
||||
if (!target_has_registers)
|
||||
return 0;
|
||||
|
||||
/* Don't attempt to use thread_db for remote targets. */
|
||||
if (!(target_can_run (¤t_target) || core_bfd))
|
||||
return 0;
|
||||
|
||||
if (thread_db_load_search ())
|
||||
return 1;
|
||||
|
||||
/* We couldn't find a libthread_db.
|
||||
If the inferior has a libpthread warn the user. */
|
||||
if (has_libpthread ())
|
||||
{
|
||||
warning (_("Unable to find libthread_db matching inferior's thread"
|
||||
" library, thread debugging will not be available."));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Either this executable isn't using libpthread at all, or it is
|
||||
statically linked. Since we can't easily distinguish these two cases,
|
||||
no warning is issued. */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue