@@ -238,7 +238,9 @@ String getBuildIDFromProgramHeaders(dl_phdr_info * info)
238238
239239 std::string_view view (reinterpret_cast <const char *>(info->dlpi_addr + phdr.p_vaddr ), phdr.p_memsz );
240240 __msan_unpoison (view.data (), view.size ());
241- return Elf::getBuildID (view.data (), view.size ());
241+ String build_id = Elf::getBuildID (view.data (), view.size ());
242+ if (!build_id.empty ()) // there may be multiple PT_NOTE segments
243+ return build_id;
242244 }
243245 return {};
244246}
@@ -316,37 +318,38 @@ void collectSymbolsFromELF(
316318 dl_phdr_info * info,
317319 std::vector<SymbolIndex::Symbol> & symbols,
318320 std::vector<SymbolIndex::Object> & objects,
319- String & build_id )
321+ String & self_build_id )
320322{
321323 String object_name;
322- String our_build_id ;
324+ String build_id ;
323325
324326#if defined (USE_MUSL)
325327 object_name = " /proc/self/exe" ;
326- our_build_id = Elf (object_name).getBuildID ();
327- build_id = our_build_id ;
328+ build_id = Elf (object_name).getBuildID ();
329+ self_build_id = build_id ;
328330#else
329331 // / MSan does not know that the program segments in memory are initialized.
330332 __msan_unpoison (info, sizeof (*info));
331333 __msan_unpoison_string (info->dlpi_name );
332334
333335 object_name = info->dlpi_name ;
334- our_build_id = getBuildIDFromProgramHeaders (info);
336+ build_id = getBuildIDFromProgramHeaders (info);
335337
336338 // / If the name is empty and there is a non-empty build-id - it's main executable.
337339 // / Find a elf file for the main executable and set the build-id.
338340 if (object_name.empty ())
339341 {
340342 object_name = " /proc/self/exe" ;
341343
342- if (our_build_id.empty ())
343- our_build_id = Elf (object_name).getBuildID ();
344-
345344 if (build_id.empty ())
346- build_id = our_build_id;
345+ build_id = Elf (object_name).getBuildID ();
346+
347+ if (self_build_id.empty ())
348+ self_build_id = build_id;
347349 }
348350#endif
349351
352+ // / Note: we load ELF from file; this doesn't work for vdso because it's only present in memory.
350353 std::error_code ec;
351354 std::filesystem::path canonical_path = std::filesystem::canonical (object_name, ec);
352355
@@ -405,17 +408,18 @@ void collectSymbolsFromELF(
405408
406409 String file_build_id = object.elf ->getBuildID ();
407410
408- if (our_build_id != file_build_id)
411+ if (build_id != file_build_id)
409412 {
410- // / If debug info doesn't correspond to our binary, fallback to the info in our binary.
413+ // / If the separate debuginfo binary doesn't correspond to the loaded binary, fallback to
414+ // / the info in the loaded binary.
411415 if (object_name != canonical_path)
412416 {
413417 object_name = canonical_path;
414418 object.elf = std::make_unique<Elf>(object_name);
415419
416420 // / But it can still be outdated, for example, if executable file was deleted from filesystem and replaced by another file.
417421 file_build_id = object.elf ->getBuildID ();
418- if (our_build_id != file_build_id)
422+ if (build_id != file_build_id)
419423 return ;
420424 }
421425 else
@@ -445,7 +449,7 @@ int collectSymbols(dl_phdr_info * info, size_t, void * data_ptr)
445449 SymbolIndex::Data & data = *reinterpret_cast <SymbolIndex::Data *>(data_ptr);
446450
447451 collectSymbolsFromProgramHeaders (info, data.symbols );
448- collectSymbolsFromELF (info, data.symbols , data.objects , data.build_id );
452+ collectSymbolsFromELF (info, data.symbols , data.objects , data.self_build_id );
449453
450454 /* Continue iterations */
451455 return 0 ;
@@ -499,10 +503,10 @@ const SymbolIndex::Object * SymbolIndex::findObject(const void * address) const
499503String SymbolIndex::getBuildIDHex () const
500504{
501505 String build_id_hex;
502- build_id_hex.resize (data.build_id .size () * 2 );
506+ build_id_hex.resize (data.self_build_id .size () * 2 );
503507
504508 char * pos = build_id_hex.data ();
505- for (auto c : data.build_id )
509+ for (auto c : data.self_build_id )
506510 {
507511 writeHexByteUppercase (c, pos);
508512 pos += 2 ;
0 commit comments