From f25a4112004efca7065068e87155757ef821d1e9 Mon Sep 17 00:00:00 2001 From: Lars Volker Date: Tue, 24 May 2016 11:49:35 -0700 Subject: [PATCH] Fix stack collection with size limit src/client/linux/minidump_writer/minidump_writer.cc:273 obtains the stack info by calling GetStackInfo(). That method will return the stack base address, aligned to the bottom of the memory page that 'stack_pointer' is in. After that it will cap the size of the memory area to be copied into the minidump to 'max_stack_len', starting from the base address, if the caller requested so. This will be the case when collecting reduced stacks, as introduced by this change: https://breakpad.appspot.com/487002/ In such cases the caller will request 2048 bytes of memory. However GetStackInfo() will have aligned the base address to the page boundary, by default 4096 bytes. If the stack, which grows towards the base address from the top ends before the 2048 bytes of the first block, then we will not collect any useful part of the stack. As a fix we skip chunks of 'max_stack_len' bytes starting from the base address until the stack_pointer is actually contained in the chunk, which we will add to the minidump file. BUG=https://bugs.chromium.org/p/google-breakpad/issues/detail?id=695 R=ivanpe@chromium.org Review URL: https://codereview.chromium.org/1959643004 . Patch from Lars Volker . --- src/client/linux/minidump_writer/minidump_writer.cc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/client/linux/minidump_writer/minidump_writer.cc b/src/client/linux/minidump_writer/minidump_writer.cc index f407caa7..86009b9f 100644 --- a/src/client/linux/minidump_writer/minidump_writer.cc +++ b/src/client/linux/minidump_writer/minidump_writer.cc @@ -275,6 +275,14 @@ class MinidumpWriter { if (max_stack_len >= 0 && stack_len > static_cast(max_stack_len)) { stack_len = max_stack_len; + // Skip empty chunks of length max_stack_len. + uintptr_t int_stack = reinterpret_cast(stack); + if (max_stack_len > 0) { + while (int_stack + max_stack_len < stack_pointer) { + int_stack += max_stack_len; + } + } + stack = reinterpret_cast(int_stack); } if (!memory.Allocate(stack_len)) return false;