diff options
author | Doug Evans <dje@google.com> | 2011-05-13 22:36:07 +0000 |
---|---|---|
committer | Doug Evans <dje@google.com> | 2011-05-13 22:36:07 +0000 |
commit | 98a5dd1327030f71f3bd23c7c3c3d87ca1e3fac4 (patch) | |
tree | 908689ee6bf3aefdb37ec0b3dd94b9c82c410e97 /gdb/linux-thread-db.c | |
parent | dbaefcf75732d6b779c408d71b79173176140296 (diff) | |
download | gdb-98a5dd1327030f71f3bd23c7c3c3d87ca1e3fac4.zip gdb-98a5dd1327030f71f3bd23c7c3c3d87ca1e3fac4.tar.gz gdb-98a5dd1327030f71f3bd23c7c3c3d87ca1e3fac4.tar.bz2 |
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.
Diffstat (limited to 'gdb/linux-thread-db.c')
-rw-r--r-- | gdb/linux-thread-db.c | 202 |
1 files changed, 134 insertions, 68 deletions
diff --git a/gdb/linux-thread-db.c b/gdb/linux-thread-db.c index 43dda48..aa8e2c7 100644 --- a/gdb/linux-thread-db.c +++ b/gdb/linux-thread-db.c @@ -812,73 +812,163 @@ try_thread_db_load (const char *library) return 0; } +/* Handle $pdir in libthread-db-search-path. + Look for libthread_db in the directory of libpthread. + The result is true for success. */ + +static int +try_thread_db_load_from_pdir (void) +{ + struct objfile *obj; + + ALL_OBJFILES (obj) + if (libpthread_name_p (obj->name)) + { + char path[PATH_MAX], *cp; + + gdb_assert (strlen (obj->name) < sizeof (path)); + strcpy (path, obj->name); + cp = strrchr (path, '/'); + + if (cp == NULL) + { + warning (_("Expected absolute pathname for libpthread in the" + " inferior, but got %s."), path); + } + else if (cp + 1 + strlen (LIBTHREAD_DB_SO) + 1 > path + sizeof (path)) + { + warning (_("Unexpected: path to libpthread in the inferior is" + " too long: %s"), path); + } + else + { + strcpy (cp + 1, LIBTHREAD_DB_SO); + if (try_thread_db_load (path)) + return 1; + } + 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. */ + to work on current inferior. + 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, ':'); + const char *this_dir = search_path; + size_t this_dir_len; 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; + this_dir_len = end - search_path; + search_path += this_dir_len + 1; } else { - size_t len = strlen (search_path); + this_dir_len = strlen (this_dir); + search_path += this_dir_len; + } - 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; + 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; + } } - strcat (path, "/"); - strcat (path, LIBTHREAD_DB_SO); - if (try_thread_db_load (path)) + else if (this_dir_len == sizeof ("$sdir") - 1 + && strncmp (this_dir, "$sdir", this_dir_len) == 0) { - rc = 1; - break; + 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 (rc == 0) - rc = try_thread_db_load (LIBTHREAD_DB_SO); + + 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 objfile *obj; struct thread_db_info *info; info = get_thread_db_info (GET_PID (inferior_ptid)); @@ -898,39 +988,15 @@ thread_db_load (void) 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)) - { - char path[PATH_MAX], *cp; - - gdb_assert (strlen (obj->name) < sizeof (path)); - strcpy (path, obj->name); - cp = strrchr (path, '/'); - - if (cp == NULL) - { - warning (_("Expected absolute pathname for libpthread in the" - " inferior, but got %s."), path); - } - else if (cp + 1 + strlen (LIBTHREAD_DB_SO) + 1 > path + sizeof (path)) - { - warning (_("Unexpected: path to libpthread in the inferior is" - " too long: %s"), path); - } - else - { - strcpy (cp + 1, LIBTHREAD_DB_SO); - 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; + /* 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. */ |