aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorted.mielczarek <ted.mielczarek@4c0a9323-5329-0410-9bdc-e9ce6186880e>2008-11-24 20:47:37 +0000
committerted.mielczarek <ted.mielczarek@4c0a9323-5329-0410-9bdc-e9ce6186880e>2008-11-24 20:47:37 +0000
commit324d84c2f6cc8a3988dd80deee8b8605e8abb6a1 (patch)
tree847b871f5d6b64c080115511f4ebea266db926db /src
parentAdded some sanity checks when iterating over threads in a crashed process. In... (diff)
downloadbreakpad-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')
-rw-r--r--src/common/linux/dump_symbols.cc90
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;
}