Linux dumper: Use pointers to SourceFileInfo structures.
Use a list of pointers to SourceFileInfo structures, not a list of the structures themselves. This is preparation for a subsequent patch which makes the data structures less STABS-specific. This patch introduces a memory leak. If an included file is referenced only by line entries for functions that LoadFuncSymbols elected to omit from the func_info list, then its SourceFileInfo structure is leaked when we destroy the name_to_file map. This leak is fixed in a subsequent patch by letting the map of files by name own the file objects. a=jimblandy r=nealsid git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@368 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
parent
4a6e708ed6
commit
e0a2512369
1 changed files with 38 additions and 29 deletions
|
@ -115,7 +115,16 @@ struct SourceFileInfo {
|
||||||
FuncInfoList func_info;
|
FuncInfoList func_info;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::list<struct SourceFileInfo> SourceFileInfoList;
|
// A simple std::list of pointers to SourceFileInfo structures, that
|
||||||
|
// owns the structures pointed to: destroying the list destroys them,
|
||||||
|
// as well.
|
||||||
|
class SourceFileInfoList : public std::list<SourceFileInfo *> {
|
||||||
|
public:
|
||||||
|
~SourceFileInfoList() {
|
||||||
|
for (iterator it = this->begin(); it != this->end(); it++)
|
||||||
|
delete *it;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Information of a symbol table.
|
// Information of a symbol table.
|
||||||
// This is the root of all types of symbol.
|
// This is the root of all types of symbol.
|
||||||
|
@ -320,14 +329,14 @@ static void AddIncludedFiles(struct SymbolInfo *symbols,
|
||||||
symbols->source_file_info.begin();
|
symbols->source_file_info.begin();
|
||||||
source_file_it != symbols->source_file_info.end();
|
source_file_it != symbols->source_file_info.end();
|
||||||
++source_file_it) {
|
++source_file_it) {
|
||||||
index_to_file[source_file_it->name_index] = &*source_file_it;
|
index_to_file[(*source_file_it)->name_index] = *source_file_it;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (SourceFileInfoList::iterator source_file_it =
|
for (SourceFileInfoList::iterator source_file_it =
|
||||||
symbols->source_file_info.begin();
|
symbols->source_file_info.begin();
|
||||||
source_file_it != symbols->source_file_info.end();
|
source_file_it != symbols->source_file_info.end();
|
||||||
++source_file_it) {
|
++source_file_it) {
|
||||||
struct SourceFileInfo &source_file = *source_file_it;
|
struct SourceFileInfo &source_file = **source_file_it;
|
||||||
|
|
||||||
for (FuncInfoList::iterator func_info_it = source_file.func_info.begin();
|
for (FuncInfoList::iterator func_info_it = source_file.func_info.begin();
|
||||||
func_info_it != source_file.func_info.end();
|
func_info_it != source_file.func_info.end();
|
||||||
|
@ -351,15 +360,15 @@ static void AddIncludedFiles(struct SymbolInfo *symbols,
|
||||||
if (! *file_map_entry) {
|
if (! *file_map_entry) {
|
||||||
// Got a new included file.
|
// Got a new included file.
|
||||||
// Those included files don't have address or line information.
|
// Those included files don't have address or line information.
|
||||||
SourceFileInfo new_file;
|
SourceFileInfo *new_file = new(SourceFileInfo);
|
||||||
new_file.name_index = line_info.source_name_index;
|
new_file->name_index = line_info.source_name_index;
|
||||||
new_file.name = reinterpret_cast<char *>(new_file.name_index +
|
new_file->name = reinterpret_cast<char *>(new_file->name_index
|
||||||
stabstr_section->sh_offset);
|
+ stabstr_section->sh_offset);
|
||||||
new_file.addr = 0;
|
new_file->addr = 0;
|
||||||
new_file.source_id = symbols->next_source_id++;
|
new_file->source_id = symbols->next_source_id++;
|
||||||
line_info.source_id = new_file.source_id;
|
line_info.source_id = new_file->source_id;
|
||||||
symbols->source_file_info.push_back(new_file);
|
symbols->source_file_info.push_back(new_file);
|
||||||
*file_map_entry = &symbols->source_file_info.back();
|
*file_map_entry = new_file;
|
||||||
} else {
|
} else {
|
||||||
// The file has been added.
|
// The file has been added.
|
||||||
line_info.source_id = (*file_map_entry)->source_id;
|
line_info.source_id = (*file_map_entry)->source_id;
|
||||||
|
@ -388,9 +397,9 @@ static bool ComputeSizeAndRVA(ElfW(Addr) loading_addr,
|
||||||
std::vector<ElfW(Addr)> boundaries;
|
std::vector<ElfW(Addr)> boundaries;
|
||||||
for (file_it = symbols->source_file_info.begin();
|
for (file_it = symbols->source_file_info.begin();
|
||||||
file_it != symbols->source_file_info.end(); file_it++) {
|
file_it != symbols->source_file_info.end(); file_it++) {
|
||||||
boundaries.push_back(file_it->addr);
|
boundaries.push_back((*file_it)->addr);
|
||||||
for (func_it = file_it->func_info.begin();
|
for (func_it = (*file_it)->func_info.begin();
|
||||||
func_it != file_it->func_info.end(); func_it++)
|
func_it != (*file_it)->func_info.end(); func_it++)
|
||||||
boundaries.push_back(func_it->addr);
|
boundaries.push_back(func_it->addr);
|
||||||
}
|
}
|
||||||
std::sort(boundaries.begin(), boundaries.end());
|
std::sort(boundaries.begin(), boundaries.end());
|
||||||
|
@ -398,8 +407,8 @@ static bool ComputeSizeAndRVA(ElfW(Addr) loading_addr,
|
||||||
int no_next_addr_count = 0;
|
int no_next_addr_count = 0;
|
||||||
for (file_it = symbols->source_file_info.begin();
|
for (file_it = symbols->source_file_info.begin();
|
||||||
file_it != symbols->source_file_info.end(); file_it++) {
|
file_it != symbols->source_file_info.end(); file_it++) {
|
||||||
for (func_it = file_it->func_info.begin();
|
for (func_it = (*file_it)->func_info.begin();
|
||||||
func_it != file_it->func_info.end(); func_it++) {
|
func_it != (*file_it)->func_info.end(); func_it++) {
|
||||||
struct FuncInfo &func_info = *func_it;
|
struct FuncInfo &func_info = *func_it;
|
||||||
assert(func_info.addr >= loading_addr);
|
assert(func_info.addr >= loading_addr);
|
||||||
func_info.rva_to_base = func_info.addr - loading_addr;
|
func_info.rva_to_base = func_info.addr - loading_addr;
|
||||||
|
@ -489,17 +498,17 @@ static bool LoadSymbols(const ElfW(Shdr) *stab_section,
|
||||||
struct nlist *cur_list = lists + i;
|
struct nlist *cur_list = lists + i;
|
||||||
if (cur_list->n_type == N_SO) {
|
if (cur_list->n_type == N_SO) {
|
||||||
// FUNC <address> <length> <param_stack_size> <function>
|
// FUNC <address> <length> <param_stack_size> <function>
|
||||||
struct SourceFileInfo source_file_info;
|
struct SourceFileInfo *source_file_info = new SourceFileInfo;
|
||||||
source_file_info.name_index = cur_list->n_un.n_strx;
|
source_file_info->name_index = cur_list->n_un.n_strx;
|
||||||
source_file_info.name = reinterpret_cast<char *>(cur_list->n_un.n_strx +
|
source_file_info->name = reinterpret_cast<char *>(cur_list->n_un.n_strx +
|
||||||
stabstr_section->sh_offset);
|
stabstr_section->sh_offset);
|
||||||
source_file_info.addr = cur_list->n_value;
|
source_file_info->addr = cur_list->n_value;
|
||||||
if (strchr(source_file_info.name, '.'))
|
if (strchr(source_file_info->name, '.'))
|
||||||
source_file_info.source_id = symbols->next_source_id++;
|
source_file_info->source_id = symbols->next_source_id++;
|
||||||
else
|
else
|
||||||
source_file_info.source_id = -1;
|
source_file_info->source_id = -1;
|
||||||
step = LoadFuncSymbols(cur_list, lists + nstab,
|
step = LoadFuncSymbols(cur_list, lists + nstab,
|
||||||
stabstr_section, &source_file_info);
|
stabstr_section, source_file_info);
|
||||||
symbols->source_file_info.push_back(source_file_info);
|
symbols->source_file_info.push_back(source_file_info);
|
||||||
}
|
}
|
||||||
i += step;
|
i += step;
|
||||||
|
@ -577,9 +586,9 @@ static bool WriteSourceFileInfo(FILE *file, const struct SymbolInfo &symbols) {
|
||||||
for (SourceFileInfoList::const_iterator it =
|
for (SourceFileInfoList::const_iterator it =
|
||||||
symbols.source_file_info.begin();
|
symbols.source_file_info.begin();
|
||||||
it != symbols.source_file_info.end(); it++) {
|
it != symbols.source_file_info.end(); it++) {
|
||||||
if (it->source_id != -1) {
|
if ((*it)->source_id != -1) {
|
||||||
const char *name = it->name;
|
const char *name = (*it)->name;
|
||||||
if (0 > fprintf(file, "FILE %d %s\n", it->source_id, name))
|
if (0 > fprintf(file, "FILE %d %s\n", (*it)->source_id, name))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -622,7 +631,7 @@ static bool WriteFunctionInfo(FILE *file, const struct SymbolInfo &symbols) {
|
||||||
for (SourceFileInfoList::const_iterator it =
|
for (SourceFileInfoList::const_iterator it =
|
||||||
symbols.source_file_info.begin();
|
symbols.source_file_info.begin();
|
||||||
it != symbols.source_file_info.end(); it++) {
|
it != symbols.source_file_info.end(); it++) {
|
||||||
const struct SourceFileInfo &file_info = *it;
|
const struct SourceFileInfo &file_info = **it;
|
||||||
for (FuncInfoList::const_iterator fiIt = file_info.func_info.begin();
|
for (FuncInfoList::const_iterator fiIt = file_info.func_info.begin();
|
||||||
fiIt != file_info.func_info.end(); fiIt++) {
|
fiIt != file_info.func_info.end(); fiIt++) {
|
||||||
const struct FuncInfo &func_info = *fiIt;
|
const struct FuncInfo &func_info = *fiIt;
|
||||||
|
|
Loading…
Reference in a new issue