diff options
author | ted.mielczarek <ted.mielczarek@4c0a9323-5329-0410-9bdc-e9ce6186880e> | 2008-11-24 20:47:37 +0000 |
---|---|---|
committer | ted.mielczarek <ted.mielczarek@4c0a9323-5329-0410-9bdc-e9ce6186880e> | 2008-11-24 20:47:37 +0000 |
commit | 324d84c2f6cc8a3988dd80deee8b8605e8abb6a1 (patch) | |
tree | 847b871f5d6b64c080115511f4ebea266db926db /src/common | |
parent | Added some sanity checks when iterating over threads in a crashed process. In... (diff) | |
download | breakpad-324d84c2f6cc8a3988dd80deee8b8605e8abb6a1.tar.xz |
Issue 259 - crash when generating large .sym files with dump_syms on Linux. Patch by login_ing@yahoo.com, r=Liu Li
git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@296 4c0a9323-5329-0410-9bdc-e9ce6186880e
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/linux/dump_symbols.cc | 90 |
1 files changed, 56 insertions, 34 deletions
diff --git a/src/common/linux/dump_symbols.cc b/src/common/linux/dump_symbols.cc index b523c5d8..9552109d 100644 --- a/src/common/linux/dump_symbols.cc +++ b/src/common/linux/dump_symbols.cc @@ -43,6 +43,7 @@ #include <algorithm> #include <functional> +#include <list> #include <vector> #include <string.h> @@ -75,6 +76,8 @@ struct LineInfo { int source_id; }; +typedef std::list<struct LineInfo> LineInfoList; + // Information of a function. struct FuncInfo { // Name of the function. @@ -93,9 +96,11 @@ struct FuncInfo { // Is there any lines included from other files? bool has_sol; // Line information array. - std::vector<struct LineInfo> line_info; + LineInfoList line_info; }; +typedef std::list<struct FuncInfo> FuncInfoList; + // Information of a source file. struct SourceFileInfo { // Name string index into the string table. @@ -107,13 +112,15 @@ struct SourceFileInfo { // Id of the source file. int source_id; // Functions information. - std::vector<struct FuncInfo> func_info; + FuncInfoList func_info; }; +typedef std::list<struct SourceFileInfo> SourceFileInfoList; + // Information of a symbol table. // This is the root of all types of symbol. struct SymbolInfo { - std::vector<struct SourceFileInfo> source_file_info; + SourceFileInfoList source_file_info; // The next source id for newly found source file. int next_source_id; @@ -270,7 +277,6 @@ static int LoadFuncSymbols(struct nlist *list, struct nlist *cur_list = list; assert(cur_list->n_type == N_SO); ++cur_list; - source_file_info->func_info.clear(); while (cur_list < list_end) { // Go until the function symbol. @@ -283,11 +289,15 @@ static int LoadFuncSymbols(struct nlist *list, } if (cur_list->n_type == N_FUN) { struct FuncInfo func_info; - memset(&func_info, 0, sizeof(func_info)); func_info.name = reinterpret_cast<char *>(cur_list->n_un.n_strx + stabstr_section->sh_offset); func_info.addr = cur_list->n_value; + func_info.rva_to_base = 0; + func_info.size = 0; + func_info.stack_param_size = 0; + func_info.has_sol = 0; + // Stack parameter size. cur_list += LoadStackParamSize(cur_list, list_end, &func_info); // Line info. @@ -295,6 +305,7 @@ static int LoadFuncSymbols(struct nlist *list, list_end, *source_file_info, &func_info); + // Functions in this module should have address bigger than the module // startring address. // There maybe a lot of duplicated entry for a function in the symbol, @@ -318,11 +329,12 @@ static bool CompareAddress(T1 *a, T2 *b) { // Return vector of pointers to the elements in the incoming array. So caller // should make sure the returned vector lives longer than the incoming vector. template<class T> -static std::vector<T *> SortByAddress(std::vector<T> *array) { +static std::vector<T *> SortByAddress(std::list<T> *array) { + typedef typename std::list<T>::iterator It; std::vector<T *> sorted_array_ptr; sorted_array_ptr.reserve(array->size()); - for (size_t i = 0; i < array->size(); ++i) - sorted_array_ptr.push_back(&(array->at(i))); + for (It it = array -> begin(); it != array -> end(); it++) + sorted_array_ptr.push_back(&(*it)); std::sort(sorted_array_ptr.begin(), sorted_array_ptr.end(), std::ptr_fun(CompareAddress<T, T>)); @@ -366,10 +378,10 @@ static ElfW(Addr) NextAddress( } static int FindFileByNameIdx(uint32_t name_index, - const std::vector<SourceFileInfo> &files) { - for (size_t i = 0; i < files.size(); ++i) { - if (files[i].name_index == name_index) - return files[i].source_id; + SourceFileInfoList &files) { + for (SourceFileInfoList::iterator it = files.begin(); it != files.end(); it++) { + if (it->name_index == name_index) + return it->source_id; } return -1; @@ -379,16 +391,20 @@ static int FindFileByNameIdx(uint32_t name_index, // Also fix the source id for the line info. static void AddIncludedFiles(struct SymbolInfo *symbols, const ElfW(Shdr) *stabstr_section) { - size_t source_file_size = symbols->source_file_info.size(); + for (SourceFileInfoList::iterator source_file_it = symbols->source_file_info.begin(); + source_file_it != symbols->source_file_info.end(); + ++source_file_it) { + struct SourceFileInfo &source_file = *source_file_it; - for (size_t i = 0; i < source_file_size; ++i) { - struct SourceFileInfo &source_file = symbols->source_file_info[i]; + for (FuncInfoList::iterator func_info_it = source_file.func_info.begin(); + func_info_it != source_file.func_info.end(); + ++func_info_it) { + struct FuncInfo &func_info = *func_info_it; - for (size_t j = 0; j < source_file.func_info.size(); ++j) { - struct FuncInfo &func_info = source_file.func_info[j]; + for (LineInfoList::iterator line_info_it = func_info.line_info.begin(); + line_info_it != func_info.line_info.end(); ++line_info_it) { + struct LineInfo &line_info = *line_info_it; - for (size_t k = 0; k < func_info.line_info.size(); ++k) { - struct LineInfo &line_info = func_info.line_info[k]; assert(line_info.source_name_index > 0); assert(source_file.name_index > 0); @@ -476,12 +492,15 @@ static bool ComputeSizeAndRVA(ElfW(Addr) loading_addr, func_info.size = kDefaultSize; } // Compute line size. - for (size_t k = 0; k < func_info.line_info.size(); ++k) { - struct LineInfo &line_info = func_info.line_info[k]; + for (LineInfoList::iterator line_info_it = func_info.line_info.begin(); + line_info_it != func_info.line_info.end(); line_info_it++) { + struct LineInfo &line_info = *line_info_it; + LineInfoList::iterator next_line_info_it = line_info_it; + next_line_info_it++; line_info.size = 0; - if (k + 1 < func_info.line_info.size()) { + if (next_line_info_it != func_info.line_info.end()) { line_info.size = - func_info.line_info[k + 1].rva_to_func - line_info.rva_to_func; + next_line_info_it->rva_to_func - line_info.rva_to_func; } else { // The last line in the function. // If we can find a function or source file symbol immediately @@ -605,11 +624,11 @@ static bool WriteModuleInfo(int fd, } static bool WriteSourceFileInfo(int fd, const struct SymbolInfo &symbols) { - for (size_t i = 0; i < symbols.source_file_info.size(); ++i) { - if (symbols.source_file_info[i].source_id != -1) { - const char *name = symbols.source_file_info[i].name; - if (!WriteFormat(fd, "FILE %d %s\n", - symbols.source_file_info[i].source_id, name)) + for (SourceFileInfoList::const_iterator it = symbols.source_file_info.begin(); + it != symbols.source_file_info.end(); it++) { + if (it->source_id != -1) { + const char *name = it->name; + if (!WriteFormat(fd, "FILE %d %s\n", it->source_id, name)) return false; } } @@ -633,8 +652,9 @@ static bool WriteOneFunction(int fd, func_info.size, func_info.stack_param_size, func_name.c_str())) { - for (size_t i = 0; i < func_info.line_info.size(); ++i) { - const struct LineInfo &line_info = func_info.line_info[i]; + for (LineInfoList::const_iterator it = func_info.line_info.begin(); + it != func_info.line_info.end(); it++) { + const struct LineInfo &line_info = *it; if (!WriteFormat(fd, "%lx %lx %d %d\n", line_info.rva_to_base, line_info.size, @@ -648,10 +668,12 @@ static bool WriteOneFunction(int fd, } static bool WriteFunctionInfo(int fd, const struct SymbolInfo &symbols) { - for (size_t i = 0; i < symbols.source_file_info.size(); ++i) { - const struct SourceFileInfo &file_info = symbols.source_file_info[i]; - for (size_t j = 0; j < file_info.func_info.size(); ++j) { - const struct FuncInfo &func_info = file_info.func_info[j]; + for (SourceFileInfoList::const_iterator it = symbols.source_file_info.begin(); + it != symbols.source_file_info.end(); it++) { + const struct SourceFileInfo &file_info = *it; + for (FuncInfoList::const_iterator fiIt = file_info.func_info.begin(); + fiIt != file_info.func_info.end(); fiIt++) { + const struct FuncInfo &func_info = *fiIt; if (!WriteOneFunction(fd, func_info)) return false; } |