Make DumpSymbols methods take a vector of debug_dirs

r=thestig at https://breakpad.appspot.com/512002/

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1102 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
ted.mielczarek@gmail.com 2013-01-22 13:36:39 +00:00
parent 834f7ee611
commit c6f6d9ef30
4 changed files with 60 additions and 44 deletions

View file

@ -387,7 +387,7 @@ template<typename ElfClass>
string ReadDebugLink(const char* debuglink,
size_t debuglink_size,
const string& obj_file,
const string& debug_dir) {
const std::vector<string>& debug_dirs) {
size_t debuglink_len = strlen(debuglink) + 5; // '\0' + CRC32.
debuglink_len = 4 * ((debuglink_len + 3) / 4); // Round to nearest 4 bytes.
@ -398,13 +398,26 @@ string ReadDebugLink(const char* debuglink,
return "";
}
string debuglink_path = debug_dir + "/" + debuglink;
int debuglink_fd = open(debuglink_path.c_str(), O_RDONLY);
if (debuglink_fd < 0) {
bool found = false;
int debuglink_fd = -1;
string debuglink_path;
std::vector<string>::const_iterator it;
for (it = debug_dirs.begin(); it < debug_dirs.end(); ++it) {
const string& debug_dir = *it;
debuglink_path = debug_dir + "/" + debuglink;
debuglink_fd = open(debuglink_path.c_str(), O_RDONLY);
if (debuglink_fd >= 0) {
found = true;
break;
}
}
if (!found) {
fprintf(stderr, "Failed to open debug ELF file '%s' for '%s': %s\n",
debuglink_path.c_str(), obj_file.c_str(), strerror(errno));
return "";
}
FDWrapper debuglink_fd_wrapper(debuglink_fd);
// TODO(thestig) check the CRC-32 at the end of the .gnu_debuglink
// section.
@ -424,8 +437,8 @@ class LoadSymbolsInfo {
public:
typedef typename ElfClass::Addr Addr;
explicit LoadSymbolsInfo(const string &dbg_dir) :
debug_dir_(dbg_dir),
explicit LoadSymbolsInfo(const std::vector<string>& dbg_dirs) :
debug_dirs_(dbg_dirs),
has_loading_addr_(false) {}
// Keeps track of which sections have been loaded so sections don't
@ -458,8 +471,8 @@ class LoadSymbolsInfo {
}
// Setters and getters
const string &debug_dir() const {
return debug_dir_;
const std::vector<string>& debug_dirs() const {
return debug_dirs_;
}
string debuglink_file() const {
@ -470,7 +483,8 @@ class LoadSymbolsInfo {
}
private:
const string &debug_dir_; // Directory with the debug ELF file.
const std::vector<string>& debug_dirs_; // Directories in which to
// search for the debug ELF file.
string debuglink_file_; // Full path to the debug ELF file.
@ -601,14 +615,14 @@ bool LoadSymbols(const string& obj_file,
sections, names,
names_end, elf_header->e_shnum);
if (gnu_debuglink_section) {
if (!info->debug_dir().empty()) {
if (!info->debug_dirs().empty()) {
const char* debuglink_contents =
GetOffset<ElfClass, char>(elf_header,
gnu_debuglink_section->sh_offset);
string debuglink_file
= ReadDebugLink<ElfClass>(debuglink_contents,
gnu_debuglink_section->sh_size,
obj_file, info->debug_dir());
obj_file, info->debug_dirs());
info->set_debuglink_file(debuglink_file);
} else {
fprintf(stderr, ".gnu_debuglink section found in '%s', "
@ -712,7 +726,7 @@ string BaseFileName(const string &filename) {
template<typename ElfClass>
bool ReadSymbolDataElfClass(const typename ElfClass::Ehdr* elf_header,
const string& obj_filename,
const string& debug_dir,
const std::vector<string>& debug_dirs,
bool cfi,
Module** out_module) {
typedef typename ElfClass::Ehdr Ehdr;
@ -744,10 +758,10 @@ bool ReadSymbolDataElfClass(const typename ElfClass::Ehdr* elf_header,
string os = "Linux";
string id = FormatIdentifier(identifier);
LoadSymbolsInfo<ElfClass> info(debug_dir);
LoadSymbolsInfo<ElfClass> info(debug_dirs);
scoped_ptr<Module> module(new Module(name, os, architecture, id));
if (!LoadSymbols<ElfClass>(obj_filename, big_endian, elf_header,
!debug_dir.empty(), &info, module.get())) {
!debug_dirs.empty(), &info, module.get())) {
const string debuglink_file = info.debuglink_file();
if (debuglink_file.empty())
return false;
@ -801,7 +815,7 @@ namespace google_breakpad {
// Not explicitly exported, but not static so it can be used in unit tests.
bool ReadSymbolDataInternal(const uint8_t* obj_file,
const string& obj_filename,
const string& debug_dir,
const std::vector<string>& debug_dirs,
bool cfi,
Module** module) {
@ -813,12 +827,12 @@ bool ReadSymbolDataInternal(const uint8_t* obj_file,
int elfclass = ElfClass(obj_file);
if (elfclass == ELFCLASS32) {
return ReadSymbolDataElfClass<ElfClass32>(
reinterpret_cast<const Elf32_Ehdr*>(obj_file), obj_filename, debug_dir,
reinterpret_cast<const Elf32_Ehdr*>(obj_file), obj_filename, debug_dirs,
cfi, module);
}
if (elfclass == ELFCLASS64) {
return ReadSymbolDataElfClass<ElfClass64>(
reinterpret_cast<const Elf64_Ehdr*>(obj_file), obj_filename, debug_dir,
reinterpret_cast<const Elf64_Ehdr*>(obj_file), obj_filename, debug_dirs,
cfi, module);
}
@ -826,11 +840,11 @@ bool ReadSymbolDataInternal(const uint8_t* obj_file,
}
bool WriteSymbolFile(const string &obj_file,
const string &debug_dir,
const std::vector<string>& debug_dirs,
bool cfi,
std::ostream &sym_stream) {
Module* module;
if (!ReadSymbolData(obj_file, debug_dir, cfi, &module))
if (!ReadSymbolData(obj_file, debug_dirs, cfi, &module))
return false;
bool result = module->Write(sym_stream, cfi);
@ -839,7 +853,7 @@ bool WriteSymbolFile(const string &obj_file,
}
bool ReadSymbolData(const string& obj_file,
const string& debug_dir,
const std::vector<string>& debug_dirs,
bool cfi,
Module** module) {
MmapWrapper map_wrapper;
@ -848,7 +862,7 @@ bool ReadSymbolData(const string& obj_file,
return false;
return ReadSymbolDataInternal(reinterpret_cast<uint8_t*>(elf_header),
obj_file, debug_dir, cfi, module);
obj_file, debug_dirs, cfi, module);
}
} // namespace google_breakpad

View file

@ -37,6 +37,7 @@
#include <iostream>
#include <string>
#include <vector>
#include "common/using_std_string.h"
@ -48,10 +49,10 @@ class Module;
// or shared library, and write it to SYM_STREAM in the Breakpad symbol
// file format.
// If OBJ_FILE has been stripped but contains a .gnu_debuglink section,
// then look for the debug file in DEBUG_DIR.
// then look for the debug file in DEBUG_DIRS.
// If CFI is set to false, then omit the CFI section.
bool WriteSymbolFile(const string &obj_file,
const string &debug_dir,
const std::vector<string>& debug_dirs,
bool cfi,
std::ostream &sym_stream);
@ -59,7 +60,7 @@ bool WriteSymbolFile(const string &obj_file,
// instead of writing it to a stream. The caller owns the resulting
// Module object and must delete it when finished.
bool ReadSymbolData(const string& obj_file,
const string& debug_dir,
const std::vector<string>& debug_dirs,
bool cfi,
Module** module);

View file

@ -46,8 +46,8 @@
namespace google_breakpad {
bool ReadSymbolDataInternal(const uint8_t* obj_file,
const string &obj_filename,
const string &debug_dir,
const string& obj_filename,
const std::vector<string>& debug_dir,
bool cfi,
Module** module);
}
@ -84,10 +84,10 @@ TEST_F(DumpSymbols, Invalid) {
memset(&header, 0, sizeof(header));
Module* module;
EXPECT_FALSE(ReadSymbolDataInternal(reinterpret_cast<uint8_t*>(&header),
"foo",
"",
true,
&module));
"foo",
vector<string>(),
true,
&module));
}
TEST_F(DumpSymbols, SimplePublic32) {
@ -117,7 +117,7 @@ TEST_F(DumpSymbols, SimplePublic32) {
Module* module;
EXPECT_TRUE(ReadSymbolDataInternal(elfdata,
"foo",
"",
vector<string>(),
true,
&module));
@ -156,7 +156,7 @@ TEST_F(DumpSymbols, SimplePublic64) {
Module* module;
EXPECT_TRUE(ReadSymbolDataInternal(elfdata,
"foo",
"",
vector<string>(),
true,
&module));

View file

@ -32,6 +32,7 @@
#include <cstring>
#include <iostream>
#include <string>
#include <vector>
#include "common/linux/dump_symbols.h"
@ -39,7 +40,7 @@ using google_breakpad::WriteSymbolFile;
int usage(const char* self) {
fprintf(stderr, "Usage: %s [OPTION] <binary-with-debugging-info> "
"[directory-for-debug-file]\n\n", self);
"[directories-for-debug-file]\n\n", self);
fprintf(stderr, "Options:\n");
fprintf(stderr, " -c Do not generate CFI section\n");
return 1;
@ -50,24 +51,24 @@ int main(int argc, char **argv) {
return usage(argv[0]);
bool cfi = true;
if (strcmp("-c", argv[1]) == 0)
int binary_index = 1;
if (strcmp("-c", argv[1]) == 0) {
cfi = false;
++binary_index;
}
if (!cfi && argc == 2)
return usage(argv[0]);
const char *binary;
std::string debug_dir;
if (cfi) {
binary = argv[1];
if (argc == 3)
debug_dir = argv[2];
} else {
binary = argv[2];
if (argc == 4)
debug_dir = argv[3];
std::vector<string> debug_dirs;
binary = argv[binary_index];
for (int debug_dir_index = binary_index + 1;
debug_dir_index < argc;
++debug_dir_index) {
debug_dirs.push_back(argv[debug_dir_index]);
}
if (!WriteSymbolFile(binary, debug_dir, cfi, std::cout)) {
if (!WriteSymbolFile(binary, debug_dirs, cfi, std::cout)) {
fprintf(stderr, "Failed to write symbol file.\n");
return 1;
}