| Index: src/client/linux/minidump_writer/linux_dumper.cc
|
| diff --git a/src/client/linux/minidump_writer/linux_dumper.cc b/src/client/linux/minidump_writer/linux_dumper.cc
|
| index 43b74ad9de7e4e536e4622aaa21d24705af5a9e0..8d4df9ad16927fc39004a14ad94181817d32cf41 100644
|
| --- a/src/client/linux/minidump_writer/linux_dumper.cc
|
| +++ b/src/client/linux/minidump_writer/linux_dumper.cc
|
| @@ -88,14 +88,16 @@ namespace google_breakpad {
|
| // All interesting auvx entry types are below AT_SYSINFO_EHDR
|
| #define AT_MAX AT_SYSINFO_EHDR
|
|
|
| -LinuxDumper::LinuxDumper(pid_t pid)
|
| +LinuxDumper::LinuxDumper(pid_t pid, const char* root_prefix)
|
| : pid_(pid),
|
| + root_prefix_(root_prefix),
|
| crash_address_(0),
|
| crash_signal_(0),
|
| crash_thread_(pid),
|
| threads_(&allocator_, 8),
|
| mappings_(&allocator_),
|
| auxv_(&allocator_, AT_MAX + 1) {
|
| + assert(root_prefix_ && my_strlen(root_prefix_) < PATH_MAX);
|
| // The passed-in size to the constructor (above) is only a hint.
|
| // Must call .resize() to do actual initialization of the elements.
|
| auxv_.resize(AT_MAX + 1);
|
| @@ -139,14 +141,9 @@ LinuxDumper::ElfFileIdentifierForMapping(const MappingInfo& mapping,
|
| return FileID::ElfFileIdentifierFromMappedFile(linux_gate, identifier);
|
| }
|
|
|
| - char filename[NAME_MAX];
|
| - size_t filename_len = my_strlen(mapping.name);
|
| - if (filename_len >= NAME_MAX) {
|
| - assert(false);
|
| + char filename[PATH_MAX];
|
| + if (!GetMappingAbsolutePath(mapping, filename))
|
| return false;
|
| - }
|
| - my_memcpy(filename, mapping.name, filename_len);
|
| - filename[filename_len] = '\0';
|
| bool filename_modified = HandleDeletedFileInMapping(filename);
|
|
|
| MemoryMappedFile mapped_file(filename, mapping.offset);
|
| @@ -156,13 +153,19 @@ LinuxDumper::ElfFileIdentifierForMapping(const MappingInfo& mapping,
|
| bool success =
|
| FileID::ElfFileIdentifierFromMappedFile(mapped_file.data(), identifier);
|
| if (success && member && filename_modified) {
|
| - mappings_[mapping_id]->name[filename_len -
|
| + mappings_[mapping_id]->name[my_strlen(mapping.name) -
|
| sizeof(kDeletedSuffix) + 1] = '\0';
|
| }
|
|
|
| return success;
|
| }
|
|
|
| +bool LinuxDumper::GetMappingAbsolutePath(const MappingInfo& mapping,
|
| + char path[PATH_MAX]) const {
|
| + return my_strlcpy(path, root_prefix_, PATH_MAX) < PATH_MAX &&
|
| + my_strlcat(path, mapping.name, PATH_MAX) < PATH_MAX;
|
| +}
|
| +
|
| namespace {
|
| bool ElfFileSoNameFromMappedFile(
|
| const void* elf_base, char* soname, size_t soname_size) {
|
| @@ -212,23 +215,16 @@ bool ElfFileSoNameFromMappedFile(
|
| // for |mapping|. If the SONAME is found copy it into the passed buffer
|
| // |soname| and return true. The size of the buffer is |soname_size|.
|
| // The SONAME will be truncated if it is too long to fit in the buffer.
|
| -bool ElfFileSoName(
|
| +bool ElfFileSoName(const LinuxDumper& dumper,
|
| const MappingInfo& mapping, char* soname, size_t soname_size) {
|
| if (IsMappedFileOpenUnsafe(mapping)) {
|
| // Not safe
|
| return false;
|
| }
|
|
|
| - char filename[NAME_MAX];
|
| - size_t filename_len = my_strlen(mapping.name);
|
| - if (filename_len >= NAME_MAX) {
|
| - assert(false);
|
| - // name too long
|
| + char filename[PATH_MAX];
|
| + if (!dumper.GetMappingAbsolutePath(mapping, filename))
|
| return false;
|
| - }
|
| -
|
| - my_memcpy(filename, mapping.name, filename_len);
|
| - filename[filename_len] = '\0';
|
|
|
| MemoryMappedFile mapped_file(filename, mapping.offset);
|
| if (!mapped_file.data() || mapped_file.size() < SELFMAG) {
|
| @@ -242,7 +238,6 @@ bool ElfFileSoName(
|
| } // namespace
|
|
|
|
|
| -// static
|
| void LinuxDumper::GetMappingEffectiveNameAndPath(const MappingInfo& mapping,
|
| char* file_path,
|
| size_t file_path_size,
|
| @@ -255,8 +250,10 @@ void LinuxDumper::GetMappingEffectiveNameAndPath(const MappingInfo& mapping,
|
| // apk on Android). We try to find the name of the shared object (SONAME) by
|
| // looking in the file for ELF sections.
|
| bool mapped_from_archive = false;
|
| - if (mapping.exec && mapping.offset != 0)
|
| - mapped_from_archive = ElfFileSoName(mapping, file_name, file_name_size);
|
| + if (mapping.exec && mapping.offset != 0) {
|
| + mapped_from_archive =
|
| + ElfFileSoName(*this, mapping, file_name, file_name_size);
|
| + }
|
|
|
| if (mapped_from_archive) {
|
| // Some tools (e.g., stackwalk) extract the basename from the pathname. In
|
| @@ -580,10 +577,13 @@ bool LinuxDumper::HandleDeletedFileInMapping(char* path) const {
|
|
|
| // Check |path| against the /proc/pid/exe 'symlink'.
|
| char exe_link[NAME_MAX];
|
| - char new_path[NAME_MAX];
|
| if (!BuildProcPath(exe_link, pid_, "exe"))
|
| return false;
|
| - if (!SafeReadLink(exe_link, new_path))
|
| + MappingInfo new_mapping = {0};
|
| + if (!SafeReadLink(exe_link, new_mapping.name))
|
| + return false;
|
| + char new_path[PATH_MAX];
|
| + if (!GetMappingAbsolutePath(new_mapping, new_path))
|
| return false;
|
| if (my_strcmp(path, new_path) != 0)
|
| return false;
|
|
|