linux, client: set module name from DT_SONAME
3e56ef9d
changed dump_syms to set the module name from DT_SONAME
expecting that clients were already using DT_SONAME when it was
present. The Breakpad client previously only used DT_SONAME as the name
for a module if it detected that it was likely mapped from a zip file.
This patch updates the Breakpad Linux client to always use the
DT_SONAME in minidumps if it's present.
Also included are changes to address comments that were missed from
that review.
Bug: 1016924
Change-Id: I4aae8c05e6793d4b0598049a8964ddd4cb0c6194
Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/1889231
Reviewed-by: Mark Mentovai <mark@chromium.org>
Reviewed-by: Mike Frysinger <vapier@chromium.org>
This commit is contained in:
parent
d27fd9ae7e
commit
5085b1d0df
2 changed files with 32 additions and 24 deletions
|
@ -473,19 +473,26 @@ void LinuxDumper::GetMappingEffectiveNameAndPath(const MappingInfo& mapping,
|
||||||
size_t file_name_size) {
|
size_t file_name_size) {
|
||||||
my_strlcpy(file_path, mapping.name, file_path_size);
|
my_strlcpy(file_path, mapping.name, file_path_size);
|
||||||
|
|
||||||
// If an executable is mapped from a non-zero offset, this is likely because
|
// Tools such as minidump_stackwalk use the name of the module to look up
|
||||||
// the executable was loaded directly from inside an archive file (e.g., an
|
// symbols produced by dump_syms. dump_syms will prefer to use a module's
|
||||||
// apk on Android). We try to find the name of the shared object (SONAME) by
|
// DT_SONAME as the module name, if one exists, and will fall back to the
|
||||||
// looking in the file for ELF sections.
|
// filesystem name of the module.
|
||||||
bool mapped_from_archive = false;
|
|
||||||
if (mapping.exec && mapping.offset != 0) {
|
// Just use the filesystem name if no SONAME is present.
|
||||||
mapped_from_archive =
|
if (!ElfFileSoName(*this, mapping, file_name, file_name_size)) {
|
||||||
ElfFileSoName(*this, mapping, file_name, file_name_size);
|
// file_path := /path/to/libname.so
|
||||||
|
// file_name := libname.so
|
||||||
|
const char* basename = my_strrchr(file_path, '/');
|
||||||
|
basename = basename == NULL ? file_path : (basename + 1);
|
||||||
|
my_strlcpy(file_name, basename, file_name_size);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mapped_from_archive) {
|
if (mapping.exec && mapping.offset != 0) {
|
||||||
// Some tools (e.g., stackwalk) extract the basename from the pathname. In
|
// If an executable is mapped from a non-zero offset, this is likely because
|
||||||
// this case, we append the file_name to the mapped archive path as follows:
|
// the executable was loaded directly from inside an archive file (e.g., an
|
||||||
|
// apk on Android).
|
||||||
|
// In this case, we append the file_name to the mapped archive path:
|
||||||
// file_name := libname.so
|
// file_name := libname.so
|
||||||
// file_path := /path/to/ARCHIVE.APK/libname.so
|
// file_path := /path/to/ARCHIVE.APK/libname.so
|
||||||
if (my_strlen(file_path) + 1 + my_strlen(file_name) < file_path_size) {
|
if (my_strlen(file_path) + 1 + my_strlen(file_name) < file_path_size) {
|
||||||
|
@ -493,12 +500,15 @@ void LinuxDumper::GetMappingEffectiveNameAndPath(const MappingInfo& mapping,
|
||||||
my_strlcat(file_path, file_name, file_path_size);
|
my_strlcat(file_path, file_name, file_path_size);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Common case:
|
// Otherwise, replace the basename with the SONAME.
|
||||||
// file_path := /path/to/libname.so
|
char* basename = const_cast<char*>(my_strrchr(file_path, '/'));
|
||||||
// file_name := libname.so
|
if (basename) {
|
||||||
const char* basename = my_strrchr(file_path, '/');
|
my_strlcpy(basename + 1, file_name,
|
||||||
basename = basename == NULL ? file_path : (basename + 1);
|
file_path_size - my_strlen(file_path) +
|
||||||
my_strlcpy(file_name, basename, file_name_size);
|
my_strlen(basename + 1));
|
||||||
|
} else {
|
||||||
|
my_strlcpy(file_path, file_name, file_path_size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -963,13 +963,11 @@ bool InitModuleForElfClass(const typename ElfClass::Ehdr* elf_header,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
string name;
|
char name_buf[NAME_MAX] = {};
|
||||||
char name_buf[NAME_MAX];
|
std::string name = google_breakpad::ElfFileSoNameFromMappedFile(
|
||||||
memset(name_buf, 0, sizeof(name_buf));
|
elf_header, name_buf, sizeof(name_buf))
|
||||||
name = google_breakpad::ElfFileSoNameFromMappedFile(elf_header, name_buf,
|
? name_buf
|
||||||
sizeof(name_buf))
|
: google_breakpad::BaseName(obj_filename);
|
||||||
? name_buf
|
|
||||||
: google_breakpad::BaseName(obj_filename);
|
|
||||||
|
|
||||||
// Add an extra "0" at the end. PDB files on Windows have an 'age'
|
// Add an extra "0" at the end. PDB files on Windows have an 'age'
|
||||||
// number appended to the end of the file identifier; this isn't
|
// number appended to the end of the file identifier; this isn't
|
||||||
|
|
Loading…
Reference in a new issue