Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(17)

Unified Diff: src/client/linux/minidump_writer/minidump_writer.cc

Issue 487002: Add optional file size limit for minidumps (Closed) Base URL: http://google-breakpad.googlecode.com/svn/trunk/
Patch Set: Created 12 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/client/linux/minidump_writer/minidump_writer.cc
===================================================================
--- src/client/linux/minidump_writer/minidump_writer.cc (revision 1065)
+++ src/client/linux/minidump_writer/minidump_writer.cc (working copy)
@@ -375,6 +375,22 @@
class MinidumpWriter {
public:
+ // The following kLimit* constants are for when minidump_size_limit_ is set
+ // and the minidump size might exceed it.
+ //
+ // Estimate for how big each thread's stack will be (in bytes).
+ static const unsigned kLimitAverageThreadStackLength = 8 * 1024;
+ // Number of threads whose stack size we don't want to limit. These base
+ // threads will simply be the first N threads returned by the dumper (although
+ // the crashing thread will never be limited). Threads beyond this count are
+ // the extra threads.
+ static const unsigned kLimitBaseThreadCount = 20;
+ // Maximum stack size to dump for any extra thread (in bytes).
+ static const unsigned kLimitMaxExtraThreadStackLen = 2 * 1024;
+ // Make sure this number of additional bytes can fit in the minidump
+ // (exclude the stack data).
+ static const unsigned kLimitMinidumpFudgeFactor = 64 * 1024;
+
MinidumpWriter(const char* minidump_path,
int minidump_fd,
const ExceptionHandler::CrashContext* context,
@@ -391,6 +407,7 @@
float_state_(NULL),
#endif
dumper_(dumper),
+ minidump_size_limit_(-1),
memory_blocks_(dumper_->allocator()),
mapping_list_(mappings),
app_memory_list_(appmem) {
@@ -629,12 +646,14 @@
}
bool FillThreadStack(MDRawThread* thread, uintptr_t stack_pointer,
- uint8_t** stack_copy) {
+ int max_stack_len, uint8_t** stack_copy) {
*stack_copy = NULL;
const void* stack;
size_t stack_len;
if (dumper_->GetStackInfo(&stack, &stack_len, stack_pointer)) {
UntypedMDRVA memory(&minidump_writer_);
+ if (max_stack_len >= 0 && stack_len > max_stack_len)
+ stack_len = max_stack_len;
if (!memory.Allocate(stack_len))
return false;
*stack_copy = reinterpret_cast<uint8_t*>(Alloc(stack_len));
@@ -666,6 +685,21 @@
*list.get() = num_threads;
+ // If there's a minidump size limit, check if it might be exceeded. Since
+ // most of the space is filled with stack data, just check against that.
+ // If this expects to exceed the limit, set extra_thread_stack_len such
+ // that any thread beyond the first kLimitBaseThreadCount threads will
+ // have only kLimitMaxExtraThreadStackLen bytes dumped.
+ int extra_thread_stack_len = -1; // default to no maximum
+ if (minidump_size_limit_ >= 0) {
+ const unsigned estimated_total_stack_size = num_threads *
+ kLimitAverageThreadStackLength;
+ const off_t estimated_minidump_size = minidump_writer_.position() +
+ estimated_total_stack_size + kLimitMinidumpFudgeFactor;
+ if (estimated_minidump_size > minidump_size_limit_)
+ extra_thread_stack_len = kLimitMaxExtraThreadStackLen;
+ }
+
for (unsigned i = 0; i < num_threads; ++i) {
MDRawThread thread;
my_memset(&thread, 0, sizeof(thread));
@@ -679,7 +713,7 @@
ucontext_ &&
!dumper_->IsPostMortem()) {
uint8_t* stack_copy;
- if (!FillThreadStack(&thread, GetStackPointer(), &stack_copy))
+ if (!FillThreadStack(&thread, GetStackPointer(), -1, &stack_copy))
return false;
// Copy 256 bytes around crashing instruction pointer to minidump.
@@ -740,7 +774,11 @@
return false;
uint8_t* stack_copy;
- if (!FillThreadStack(&thread, info.stack_pointer, &stack_copy))
+ int max_stack_len = -1; // default to no maximum for this thread
+ if (minidump_size_limit_ >= 0 && i >= kLimitBaseThreadCount)
+ max_stack_len = extra_thread_stack_len;
+ if (!FillThreadStack(&thread, info.stack_pointer, max_stack_len,
+ &stack_copy))
return false;
TypedMDRVA<RawContextCPU> cpu(&minidump_writer_);
@@ -1109,6 +1147,8 @@
#endif
}
+ void set_minidump_size_limit(off_t limit) { minidump_size_limit_ = limit; }
+
private:
void* Alloc(unsigned bytes) {
return dumper_->allocator()->Alloc(bytes);
@@ -1436,6 +1476,7 @@
const struct _libc_fpstate* const float_state_; // ditto
LinuxDumper* dumper_;
MinidumpFileWriter minidump_writer_;
+ off_t minidump_size_limit_;
MDLocationDescriptor crashing_thread_context_;
// Blocks of memory written to the dump. These are all currently
// written while writing the thread list stream, but saved here
@@ -1451,21 +1492,26 @@
bool WriteMinidumpImpl(const char* minidump_path,
int minidump_fd,
+ off_t minidump_size_limit,
pid_t crashing_process,
const void* blob, size_t blob_size,
const MappingList& mappings,
const AppMemoryList& appmem) {
- if (blob_size != sizeof(ExceptionHandler::CrashContext))
- return false;
- const ExceptionHandler::CrashContext* context =
- reinterpret_cast<const ExceptionHandler::CrashContext*>(blob);
LinuxPtraceDumper dumper(crashing_process);
- dumper.set_crash_address(
- reinterpret_cast<uintptr_t>(context->siginfo.si_addr));
- dumper.set_crash_signal(context->siginfo.si_signo);
- dumper.set_crash_thread(context->tid);
+ const ExceptionHandler::CrashContext* context = NULL;
+ if (blob) {
+ if (blob_size != sizeof(ExceptionHandler::CrashContext))
+ return false;
+ context = reinterpret_cast<const ExceptionHandler::CrashContext*>(blob);
+ dumper.set_crash_address(
+ reinterpret_cast<uintptr_t>(context->siginfo.si_addr));
+ dumper.set_crash_signal(context->siginfo.si_signo);
+ dumper.set_crash_thread(context->tid);
+ }
MinidumpWriter writer(minidump_path, minidump_fd, context, mappings,
appmem, &dumper);
+ // Set desired limit for file size of minidump (-1 means no limit).
+ writer.set_minidump_size_limit(minidump_size_limit);
if (!writer.Init())
return false;
return writer.Dump();
@@ -1477,13 +1523,15 @@
bool WriteMinidump(const char* minidump_path, pid_t crashing_process,
const void* blob, size_t blob_size) {
- return WriteMinidumpImpl(minidump_path, -1, crashing_process, blob, blob_size,
+ return WriteMinidumpImpl(minidump_path, -1, -1,
+ crashing_process, blob, blob_size,
MappingList(), AppMemoryList());
}
bool WriteMinidump(int minidump_fd, pid_t crashing_process,
const void* blob, size_t blob_size) {
- return WriteMinidumpImpl(NULL, minidump_fd, crashing_process, blob, blob_size,
+ return WriteMinidumpImpl(NULL, minidump_fd, -1,
+ crashing_process, blob, blob_size,
MappingList(), AppMemoryList());
}
@@ -1504,7 +1552,8 @@
const void* blob, size_t blob_size,
const MappingList& mappings,
const AppMemoryList& appmem) {
- return WriteMinidumpImpl(minidump_path, -1, crashing_process, blob, blob_size,
+ return WriteMinidumpImpl(minidump_path, -1, -1, crashing_process,
+ blob, blob_size,
mappings, appmem);
}
@@ -1512,10 +1561,31 @@
const void* blob, size_t blob_size,
const MappingList& mappings,
const AppMemoryList& appmem) {
- return WriteMinidumpImpl(NULL, minidump_fd, crashing_process, blob, blob_size,
+ return WriteMinidumpImpl(NULL, minidump_fd, -1, crashing_process,
+ blob, blob_size,
mappings, appmem);
}
+bool WriteMinidump(const char* minidump_path, off_t minidump_size_limit,
+ pid_t crashing_process,
+ const void* blob, size_t blob_size,
+ const MappingList& mappings,
+ const AppMemoryList& appmem) {
+ return WriteMinidumpImpl(minidump_path, -1, minidump_size_limit,
+ crashing_process, blob, blob_size,
+ mappings, appmem);
+}
+
+bool WriteMinidump(int minidump_fd, off_t minidump_size_limit,
+ pid_t crashing_process,
+ const void* blob, size_t blob_size,
+ const MappingList& mappings,
+ const AppMemoryList& appmem) {
+ return WriteMinidumpImpl(NULL, minidump_fd, minidump_size_limit,
+ crashing_process, blob, blob_size,
+ mappings, appmem);
+}
+
bool WriteMinidump(const char* filename,
const MappingList& mappings,
const AppMemoryList& appmem,

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld 1004:630ec63f810e-tainted