Fix WriteMemoryListStream to remove an extraneous loop index variable increment.

Patch by timeless <timeless@mozdev.org>, R=me, unittest by me.
See https://bugzilla.mozilla.org/show_bug.cgi?id=615534

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@735 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
ted.mielczarek 2010-11-30 19:19:31 +00:00
parent ccc2446863
commit 30b075c4a5
2 changed files with 62 additions and 2 deletions

View File

@ -641,7 +641,7 @@ bool MinidumpGenerator::WriteMemoryListStream(
unsigned int i; unsigned int i;
for (i = 0; i < memory_count; ++i) { for (i = 0; i < memory_count; ++i) {
list.CopyIndexAfterObject(i++, &memory_blocks_[i], list.CopyIndexAfterObject(i, &memory_blocks_[i],
sizeof(MDMemoryDescriptor)); sizeof(MDMemoryDescriptor));
} }

View File

@ -29,6 +29,7 @@
// exception_handler_test.cc: Unit tests for google_breakpad::ExceptionHandler // exception_handler_test.cc: Unit tests for google_breakpad::ExceptionHandler
#include <pthread.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <unistd.h> #include <unistd.h>
@ -241,7 +242,7 @@ TEST_F(ExceptionHandlerTest, InstructionPointerMemory) {
// of the block of memory, because the minidump should contain 128 // of the block of memory, because the minidump should contain 128
// bytes on either side of the instruction pointer. // bytes on either side of the instruction pointer.
memcpy(memory + kOffset, instructions, sizeof(instructions)); memcpy(memory + kOffset, instructions, sizeof(instructions));
// Now execute the instructions, which should crash. // Now execute the instructions, which should crash.
typedef void (*void_function)(void); typedef void (*void_function)(void);
void_function memory_function = void_function memory_function =
@ -594,4 +595,63 @@ TEST_F(ExceptionHandlerTest, InstructionPointerMemoryNullPointer) {
ASSERT_EQ((unsigned int)1, memory_list->region_count()); ASSERT_EQ((unsigned int)1, memory_list->region_count());
} }
static void *Junk(void *) {
sleep(1000000);
return NULL;
}
// Test that the memory list gets written correctly when multiple
// threads are running.
TEST_F(ExceptionHandlerTest, MemoryListMultipleThreads) {
// Give the child process a pipe to report back on.
int fds[2];
ASSERT_EQ(0, pipe(fds));
pid_t pid = fork();
if (pid == 0) {
close(fds[0]);
ExceptionHandler eh(tempDir.path, NULL, MDCallback, &fds[1], true, NULL);
// Run an extra thread so >2 memory regions will be written.
pthread_t junk_thread;
if (pthread_create(&junk_thread, NULL, Junk, NULL) == 0)
pthread_detach(junk_thread);
// Just crash.
Crasher();
// not reached
exit(1);
}
// In the parent process.
ASSERT_NE(-1, pid);
close(fds[1]);
// Wait for the background process to return the minidump file.
close(fds[1]);
char minidump_file[PATH_MAX];
ssize_t nbytes = read(fds[0], minidump_file, sizeof(minidump_file));
ASSERT_NE(0, nbytes);
// Ensure that minidump file exists and is > 0 bytes.
struct stat st;
ASSERT_EQ(0, stat(minidump_file, &st));
ASSERT_LT(0, st.st_size);
// Child process should have exited with a zero status.
int ret;
ASSERT_EQ(pid, waitpid(pid, &ret, 0));
EXPECT_NE(0, WIFEXITED(ret));
EXPECT_EQ(0, WEXITSTATUS(ret));
// Read the minidump, and verify that the memory list can be read.
Minidump minidump(minidump_file);
ASSERT_TRUE(minidump.Read());
MinidumpMemoryList* memory_list = minidump.GetMemoryList();
ASSERT_TRUE(memory_list);
// Verify that there are three memory regions:
// one per thread, and one for the instruction pointer memory.
ASSERT_EQ((unsigned int)3, memory_list->region_count());
}
} }