Eliminate usage of vector<>[0] for 0-sized vectors in processor library (#84).
r=bryner
8eb9277ac0
git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@72 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
parent
c297c50f83
commit
373c49b416
1 changed files with 130 additions and 116 deletions
|
@ -643,6 +643,9 @@ const u_int8_t* MinidumpMemoryRegion::GetMemory() {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (!memory_) {
|
if (!memory_) {
|
||||||
|
if (descriptor_->memory.data_size == 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
if (!minidump_->SeekSet(descriptor_->memory.rva))
|
if (!minidump_->SeekSet(descriptor_->memory.rva))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
@ -920,31 +923,34 @@ bool MinidumpThreadList::Read(u_int32_t expected_size) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(mmentovai): verify rational size!
|
if (thread_count) {
|
||||||
scoped_ptr<MinidumpThreads> threads(
|
// TODO(mmentovai): verify rational size!
|
||||||
new MinidumpThreads(thread_count, MinidumpThread(minidump_)));
|
scoped_ptr<MinidumpThreads> threads(
|
||||||
|
new MinidumpThreads(thread_count, MinidumpThread(minidump_)));
|
||||||
|
|
||||||
for (unsigned int thread_index = 0;
|
for (unsigned int thread_index = 0;
|
||||||
thread_index < thread_count;
|
thread_index < thread_count;
|
||||||
++thread_index) {
|
++thread_index) {
|
||||||
MinidumpThread* thread = &(*threads)[thread_index];
|
MinidumpThread* thread = &(*threads)[thread_index];
|
||||||
|
|
||||||
// Assume that the file offset is correct after the last read.
|
// Assume that the file offset is correct after the last read.
|
||||||
if (!thread->Read())
|
if (!thread->Read())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
u_int32_t thread_id;
|
u_int32_t thread_id;
|
||||||
if (!thread->GetThreadID(&thread_id))
|
if (!thread->GetThreadID(&thread_id))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (GetThreadByID(thread_id)) {
|
if (GetThreadByID(thread_id)) {
|
||||||
// Another thread with this ID is already in the list. Data error.
|
// Another thread with this ID is already in the list. Data error.
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
id_to_thread_map_[thread_id] = thread;
|
||||||
}
|
}
|
||||||
id_to_thread_map_[thread_id] = thread;
|
|
||||||
|
threads_ = threads.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
threads_ = threads.release();
|
|
||||||
thread_count_ = thread_count;
|
thread_count_ = thread_count;
|
||||||
|
|
||||||
valid_ = true;
|
valid_ = true;
|
||||||
|
@ -1275,7 +1281,8 @@ const string* MinidumpModule::GetDebugFilename() {
|
||||||
// UTF16ToUTF8 expects a vector<u_int16_t>, so create a temporary one and
|
// UTF16ToUTF8 expects a vector<u_int16_t>, so create a temporary one and
|
||||||
// copy the UTF-16 data into it.
|
// copy the UTF-16 data into it.
|
||||||
vector<u_int16_t> string_utf16(utf16_words);
|
vector<u_int16_t> string_utf16(utf16_words);
|
||||||
memcpy(&string_utf16[0], &misc_record->data, bytes);
|
if (utf16_words)
|
||||||
|
memcpy(&string_utf16[0], &misc_record->data, bytes);
|
||||||
|
|
||||||
// GetMiscRecord already byte-swapped the data[] field if it contains
|
// GetMiscRecord already byte-swapped the data[] field if it contains
|
||||||
// UTF-16, so pass false as the swap argument.
|
// UTF-16, so pass false as the swap argument.
|
||||||
|
@ -1451,29 +1458,32 @@ bool MinidumpModuleList::Read(u_int32_t expected_size) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(mmentovai): verify rational size!
|
if (module_count) {
|
||||||
scoped_ptr<MinidumpModules> modules(
|
// TODO(mmentovai): verify rational size!
|
||||||
new MinidumpModules(module_count, MinidumpModule(minidump_)));
|
scoped_ptr<MinidumpModules> modules(
|
||||||
|
new MinidumpModules(module_count, MinidumpModule(minidump_)));
|
||||||
|
|
||||||
for (unsigned int module_index = 0;
|
for (unsigned int module_index = 0;
|
||||||
module_index < module_count;
|
module_index < module_count;
|
||||||
++module_index) {
|
++module_index) {
|
||||||
MinidumpModule* module = &(*modules)[module_index];
|
MinidumpModule* module = &(*modules)[module_index];
|
||||||
|
|
||||||
// Assume that the file offset is correct after the last read.
|
// Assume that the file offset is correct after the last read.
|
||||||
if (!module->Read())
|
if (!module->Read())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
u_int64_t base_address = module->base_address();
|
u_int64_t base_address = module->base_address();
|
||||||
u_int64_t module_size = module->size();
|
u_int64_t module_size = module->size();
|
||||||
if (base_address == (u_int64_t)-1)
|
if (base_address == static_cast<u_int64_t>(-1))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!range_map_->StoreRange(base_address, module_size, module_index))
|
if (!range_map_->StoreRange(base_address, module_size, module_index))
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
modules_ = modules.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
modules_ = modules.release();
|
|
||||||
module_count_ = module_count;
|
module_count_ = module_count;
|
||||||
|
|
||||||
valid_ = true;
|
valid_ = true;
|
||||||
|
@ -1566,46 +1576,49 @@ bool MinidumpMemoryList::Read(u_int32_t expected_size) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(mmentovai): verify rational size!
|
if (region_count) {
|
||||||
scoped_ptr<MemoryDescriptors> descriptors(
|
// TODO(mmentovai): verify rational size!
|
||||||
new MemoryDescriptors(region_count));
|
scoped_ptr<MemoryDescriptors> descriptors(
|
||||||
|
new MemoryDescriptors(region_count));
|
||||||
|
|
||||||
// Read the entire array in one fell swoop, instead of reading one entry
|
// Read the entire array in one fell swoop, instead of reading one entry
|
||||||
// at a time in the loop.
|
// at a time in the loop.
|
||||||
if (!minidump_->ReadBytes(&(*descriptors)[0],
|
if (!minidump_->ReadBytes(&(*descriptors)[0],
|
||||||
sizeof(MDMemoryDescriptor) * region_count)) {
|
sizeof(MDMemoryDescriptor) * region_count)) {
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
scoped_ptr<MemoryRegions> regions(
|
|
||||||
new MemoryRegions(region_count, MinidumpMemoryRegion(minidump_)));
|
|
||||||
|
|
||||||
for (unsigned int region_index = 0;
|
|
||||||
region_index < region_count;
|
|
||||||
++region_index) {
|
|
||||||
MDMemoryDescriptor* descriptor = &(*descriptors)[region_index];
|
|
||||||
|
|
||||||
if (minidump_->swap())
|
|
||||||
Swap(&*descriptor);
|
|
||||||
|
|
||||||
u_int64_t base_address = descriptor->start_of_memory_range;
|
|
||||||
u_int32_t region_size = descriptor->memory.data_size;
|
|
||||||
|
|
||||||
// Check for base + size overflow or undersize. A separate size==0
|
|
||||||
// check is needed in case base == 0.
|
|
||||||
u_int64_t high_address = base_address + region_size - 1;
|
|
||||||
if (region_size == 0 || high_address < base_address)
|
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!range_map_->StoreRange(base_address, region_size, region_index))
|
scoped_ptr<MemoryRegions> regions(
|
||||||
return false;
|
new MemoryRegions(region_count, MinidumpMemoryRegion(minidump_)));
|
||||||
|
|
||||||
(*regions)[region_index].SetDescriptor(descriptor);
|
for (unsigned int region_index = 0;
|
||||||
|
region_index < region_count;
|
||||||
|
++region_index) {
|
||||||
|
MDMemoryDescriptor* descriptor = &(*descriptors)[region_index];
|
||||||
|
|
||||||
|
if (minidump_->swap())
|
||||||
|
Swap(descriptor);
|
||||||
|
|
||||||
|
u_int64_t base_address = descriptor->start_of_memory_range;
|
||||||
|
u_int32_t region_size = descriptor->memory.data_size;
|
||||||
|
|
||||||
|
// Check for base + size overflow or undersize. A separate size==0
|
||||||
|
// check is needed in case base == 0.
|
||||||
|
u_int64_t high_address = base_address + region_size - 1;
|
||||||
|
if (region_size == 0 || high_address < base_address)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!range_map_->StoreRange(base_address, region_size, region_index))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
(*regions)[region_index].SetDescriptor(descriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
descriptors_ = descriptors.release();
|
||||||
|
regions_ = regions.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
region_count_ = region_count;
|
region_count_ = region_count;
|
||||||
descriptors_ = descriptors.release();
|
|
||||||
regions_ = regions.release();
|
|
||||||
|
|
||||||
valid_ = true;
|
valid_ = true;
|
||||||
return true;
|
return true;
|
||||||
|
@ -2110,7 +2123,7 @@ void MinidumpAirbagInfo::Print() {
|
||||||
Minidump::Minidump(const string& path)
|
Minidump::Minidump(const string& path)
|
||||||
: header_(),
|
: header_(),
|
||||||
directory_(NULL),
|
directory_(NULL),
|
||||||
stream_map_(NULL),
|
stream_map_(new MinidumpStreamMap()),
|
||||||
path_(path),
|
path_(path),
|
||||||
fd_(-1),
|
fd_(-1),
|
||||||
swap_(false),
|
swap_(false),
|
||||||
|
@ -2147,8 +2160,7 @@ bool Minidump::Read() {
|
||||||
// Invalidate cached data.
|
// Invalidate cached data.
|
||||||
delete directory_;
|
delete directory_;
|
||||||
directory_ = NULL;
|
directory_ = NULL;
|
||||||
delete stream_map_;
|
stream_map_->clear();
|
||||||
stream_map_ = NULL;
|
|
||||||
|
|
||||||
valid_ = false;
|
valid_ = false;
|
||||||
|
|
||||||
|
@ -2195,57 +2207,56 @@ bool Minidump::Read() {
|
||||||
if (!SeekSet(header_.stream_directory_rva))
|
if (!SeekSet(header_.stream_directory_rva))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// TODO(mmentovai): verify rational size!
|
if (header_.stream_count) {
|
||||||
scoped_ptr<MinidumpDirectoryEntries> directory(
|
// TODO(mmentovai): verify rational size!
|
||||||
new MinidumpDirectoryEntries(header_.stream_count));
|
scoped_ptr<MinidumpDirectoryEntries> directory(
|
||||||
|
new MinidumpDirectoryEntries(header_.stream_count));
|
||||||
|
|
||||||
// Read the entire array in one fell swoop, instead of reading one entry
|
// Read the entire array in one fell swoop, instead of reading one entry
|
||||||
// at a time in the loop.
|
// at a time in the loop.
|
||||||
if (!ReadBytes(&(*directory)[0],
|
if (!ReadBytes(&(*directory)[0],
|
||||||
sizeof(MDRawDirectory) * header_.stream_count))
|
sizeof(MDRawDirectory) * header_.stream_count))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
scoped_ptr<MinidumpStreamMap> stream_map(new MinidumpStreamMap());
|
for (unsigned int stream_index = 0;
|
||||||
|
stream_index < header_.stream_count;
|
||||||
|
++stream_index) {
|
||||||
|
MDRawDirectory* directory_entry = &(*directory)[stream_index];
|
||||||
|
|
||||||
for (unsigned int stream_index = 0;
|
if (swap_) {
|
||||||
stream_index < header_.stream_count;
|
Swap(&directory_entry->stream_type);
|
||||||
++stream_index) {
|
Swap(&directory_entry->location);
|
||||||
MDRawDirectory* directory_entry = &(*directory)[stream_index];
|
}
|
||||||
|
|
||||||
if (swap_) {
|
// Initialize the stream_map_ map, which speeds locating a stream by
|
||||||
Swap(&directory_entry->stream_type);
|
// type.
|
||||||
Swap(&directory_entry->location);
|
unsigned int stream_type = directory_entry->stream_type;
|
||||||
}
|
switch (stream_type) {
|
||||||
|
case MD_THREAD_LIST_STREAM:
|
||||||
// Initialize the stream_map map, which speeds locating a stream by
|
case MD_MODULE_LIST_STREAM:
|
||||||
// type.
|
case MD_MEMORY_LIST_STREAM:
|
||||||
unsigned int stream_type = directory_entry->stream_type;
|
case MD_EXCEPTION_STREAM:
|
||||||
switch (stream_type) {
|
case MD_SYSTEM_INFO_STREAM:
|
||||||
case MD_THREAD_LIST_STREAM:
|
case MD_MISC_INFO_STREAM:
|
||||||
case MD_MODULE_LIST_STREAM:
|
case MD_AIRBAG_INFO_STREAM: {
|
||||||
case MD_MEMORY_LIST_STREAM:
|
if (stream_map_->find(stream_type) != stream_map_->end()) {
|
||||||
case MD_EXCEPTION_STREAM:
|
// Another stream with this type was already found. A minidump
|
||||||
case MD_SYSTEM_INFO_STREAM:
|
// file should contain at most one of each of these stream types.
|
||||||
case MD_MISC_INFO_STREAM:
|
return false;
|
||||||
case MD_AIRBAG_INFO_STREAM: {
|
}
|
||||||
if (stream_map->find(stream_type) != stream_map->end()) {
|
// Fall through to default
|
||||||
// Another stream with this type was already found. A minidump
|
|
||||||
// file should contain at most one of each of these stream types.
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
// Fall through to default
|
|
||||||
}
|
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
// Overwrites for stream types other than those above, but it's
|
// Overwrites for stream types other than those above, but it's
|
||||||
// expected to be the user's burden in that case.
|
// expected to be the user's burden in that case.
|
||||||
(*stream_map)[stream_type].stream_index = stream_index;
|
(*stream_map_)[stream_type].stream_index = stream_index;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
directory_ = directory.release();
|
directory_ = directory.release();
|
||||||
stream_map_ = stream_map.release();
|
}
|
||||||
|
|
||||||
valid_ = true;
|
valid_ = true;
|
||||||
return true;
|
return true;
|
||||||
|
@ -2391,8 +2402,11 @@ string* Minidump::ReadString(off_t offset) {
|
||||||
// TODO(mmentovai): verify rational size!
|
// TODO(mmentovai): verify rational size!
|
||||||
vector<u_int16_t> string_utf16(utf16_words);
|
vector<u_int16_t> string_utf16(utf16_words);
|
||||||
|
|
||||||
if (!ReadBytes(&string_utf16[0], bytes))
|
if (utf16_words) {
|
||||||
return NULL;
|
if (!ReadBytes(&string_utf16[0], bytes)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return UTF16ToUTF8(string_utf16, swap_);
|
return UTF16ToUTF8(string_utf16, swap_);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue