static int thread_db_load_search (void) { VEC (char_ptr) *dir_vec; char *this_dir; int i, rc = 0; if (libthread_db_search_path == NULL) libthread_db_search_path = xstrdup (LIBTHREAD_DB_SEARCH_PATH); dir_vec = dirnames_to_char_ptr_vec (libthread_db_search_path); for (i = 0; VEC_iterate (char_ptr, dir_vec, i, this_dir); ++i) { 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; } } } free_char_ptr_vec (dir_vec); if (debug_threads) debug_printf ("thread_db_load_search returning %d\n", rc); return rc; }
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; } } } if (debug_threads) debug_printf ("thread_db_load_search returning %d\n", rc); return rc; }
gdb_bfd_ref_ptr build_id_to_debug_bfd (size_t build_id_len, const bfd_byte *build_id) { char *link, *debugdir; VEC (char_ptr) *debugdir_vec; struct cleanup *back_to; int ix; gdb_bfd_ref_ptr abfd; int alloc_len; /* DEBUG_FILE_DIRECTORY/.build-id/ab/cdef */ alloc_len = (strlen (debug_file_directory) + (sizeof "/.build-id/" - 1) + 1 + 2 * build_id_len + (sizeof ".debug" - 1) + 1); link = (char *) alloca (alloc_len); /* Keep backward compatibility so that DEBUG_FILE_DIRECTORY being "" will cause "/.build-id/..." lookups. */ debugdir_vec = dirnames_to_char_ptr_vec (debug_file_directory); back_to = make_cleanup_free_char_ptr_vec (debugdir_vec); for (ix = 0; VEC_iterate (char_ptr, debugdir_vec, ix, debugdir); ++ix) { size_t debugdir_len = strlen (debugdir); const gdb_byte *data = build_id; size_t size = build_id_len; char *s; char *filename = NULL; struct cleanup *inner; memcpy (link, debugdir, debugdir_len); s = &link[debugdir_len]; s += sprintf (s, "/.build-id/"); if (size > 0) { size--; s += sprintf (s, "%02x", (unsigned) *data++); } if (size > 0) *s++ = '/'; while (size-- > 0) s += sprintf (s, "%02x", (unsigned) *data++); strcpy (s, ".debug"); if (separate_debug_file_debug) printf_unfiltered (_(" Trying %s\n"), link); /* lrealpath() is expensive even for the usually non-existent files. */ if (access (link, F_OK) == 0) filename = lrealpath (link); if (filename == NULL) continue; /* We expect to be silent on the non-existing files. */ inner = make_cleanup (xfree, filename); abfd = gdb_bfd_open (filename, gnutarget, -1); do_cleanups (inner); if (abfd == NULL) continue; if (build_id_verify (abfd.get(), build_id_len, build_id)) break; abfd.release (); } do_cleanups (back_to); return abfd; }