Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(282)

Issue 2784783003: On heap tracking datastructure overflow, degrade instead of CHECK() (Closed)

Created:
3 years, 8 months ago by awong
Modified:
3 years, 8 months ago
CC:
chromium-reviews, tracing+reviews_chromium.org, wfh+watch_chromium.org, vmpstr+watch_chromium.org
Target Ref:
refs/heads/master
Project:
chromium
Visibility:
Public.

Description

On heap tracking datastructure overflow, degrade instead of CHECK() This allows the heap profiler to on systems with heavy memory usage (sometimes caused by strange profiles). Next step is to surface the overflow on the tracing UI. BUG=698079

Patch Set 1 #

Total comments: 16

Patch Set 2 : Address comments. #

Total comments: 3
Unified diffs Side-by-side diffs Delta from patch set Stats (+50 lines, -41 lines) Patch
M base/trace_event/heap_profiler_allocation_register.h View 1 7 chunks +37 lines, -30 lines 1 comment Download
M base/trace_event/heap_profiler_allocation_register.cc View 1 3 chunks +10 lines, -5 lines 2 comments Download
M base/trace_event/heap_profiler_allocation_register_unittest.cc View 2 chunks +3 lines, -6 lines 0 comments Download

Messages

Total messages: 17 (11 generated)
awong
3 years, 8 months ago (2017-03-30 00:17:57 UTC) #2
Primiano Tucci (use gerrit)
Makes sense to me, just some comments https://codereview.chromium.org/2784783003/diff/1/base/trace_event/heap_profiler_allocation_register.cc File base/trace_event/heap_profiler_allocation_register.cc (right): https://codereview.chromium.org/2784783003/diff/1/base/trace_event/heap_profiler_allocation_register.cc#newcode84 base/trace_event/heap_profiler_allocation_register.cc:84: bool AllocationRegister::Insert(const ...
3 years, 8 months ago (2017-03-30 13:32:41 UTC) #8
DmitrySkiba
This CL misses a case when backtrace hastable (backtraces_, see InsertBacktrace) overflows. I've seen that ...
3 years, 8 months ago (2017-03-30 17:57:58 UTC) #9
Primiano Tucci (use gerrit)
On 2017/03/30 17:57:58, DmitrySkiba wrote: > This CL misses a case when backtrace hastable (backtraces_, ...
3 years, 8 months ago (2017-03-30 18:58:14 UTC) #10
awong
PTAL https://codereview.chromium.org/2784783003/diff/1/base/trace_event/heap_profiler_allocation_register.cc File base/trace_event/heap_profiler_allocation_register.cc (right): https://codereview.chromium.org/2784783003/diff/1/base/trace_event/heap_profiler_allocation_register.cc#newcode84 base/trace_event/heap_profiler_allocation_register.cc:84: bool AllocationRegister::Insert(const void* address, On 2017/03/30 13:32:40, Primiano ...
3 years, 8 months ago (2017-03-31 04:28:31 UTC) #13
Primiano Tucci (use gerrit)
3 years, 8 months ago (2017-03-31 19:05:47 UTC) #17
Unfortunately while most of this CL looks good to me:
- MSVC is unhappy (See the bug linked below)
- there is a bug with the case when we overflow of backtraces before allocations
(see test attached).

Gievn that you are OOO, I took the liberty of rewriting this CL in
https://codereview.chromium.org/2787383002/ .
I kept all ajwong changes, modulo:
 - fixing the crash
 - fixing the -1 MSVC issue
 - improving the test.
 - adding the backtrace sentinel
See delta patchset there.

ajwong: I thought more and we *Really* need a sentinel for the backtrace as
dskiba@ suggested. Even if we are very carefully of keeping the -1 around, that
will still crash the serializer when accessing the backtrace for an allocation
that was recorded when the backtrace table was out of storage.

https://codereview.chromium.org/2784783003/diff/1/base/trace_event/heap_profi...
File base/trace_event/heap_profiler_allocation_register.cc (right):

https://codereview.chromium.org/2784783003/diff/1/base/trace_event/heap_profi...
base/trace_event/heap_profiler_allocation_register.cc:84: bool
AllocationRegister::Insert(const void* address,
On 2017/03/31 04:28:30, awong wrote:
> On 2017/03/30 13:32:40, Primiano Tucci wrote:
> > do we need this bool here?
> > If it's just for the test I'd just keep this a void and check that:
> > - the insert doesn't fail.
> > - the address is not in the list.
> 
> I feel like the API is cleaner to have a bool return. Is there a downside to
> this?

Not strong enough to justify another round on this. You won. :P

https://codereview.chromium.org/2784783003/diff/1/base/trace_event/heap_profi...
File base/trace_event/heap_profiler_allocation_register.h (left):

https://codereview.chromium.org/2784783003/diff/1/base/trace_event/heap_profi...
base/trace_event/heap_profiler_allocation_register.h:51: static const KVIndex
kInvalidKVIndex = static_cast<KVIndex>(-1);
On 2017/03/31 04:28:31, awong wrote:
> On 2017/03/30 13:32:40, Primiano Tucci wrote:
> > uh why? initializing a static const int-type in a header should always be
> fine.
> > I see this in other places, e.g.:
> > tools/gn/ordered_set.h
> > base/numerics/safe_conversions_impl.h
> > components/sync/base/enum_set.h
> > 
> > Eventually a constexpr might solve ambiguities, but I am not sure that will
> > build on all compilers. maybe try?
> 
> This is a common C++ mistake that only often doesn't bite people.  The
relevant
> spec citation is [class.static.data]p3
> 
> """
> 3 If a non-volatile const static data member is of integral or enumeration
type,
> its declaration in the class
> definition can specify a brace-or-equal-initializer in which every
> initializer-clause that is an assignmentexpression
> is a constant expression (5.19). A static data member of literal type can be
> declared in the
> class definition with the constexpr specifier; if so, its declaration shall
> specify a brace-or-equal-initializer
> in which every initializer-clause that is an assignment-expression is a
constant
> expression. [ Note: In both
> these cases, the member may appear in constant expressions. — end note ] The
> member shall still be defined
> in a namespace scope if it is odr-used (3.2) in the program and the namespace
> scope definition shall not
> contain an initializer
> """
> 
> Basically, they made an exception for integral types and enums such that you
can
> specify the value in the header WITHOUT turning the line into a _definition_
> thereby allowing constant propagation WITHOUT also creating ODR violations.
> 
> However, technically, you must still define the variable external to the
class.
> Normally you'd just do this in a .cc, but for templates, that doesn't work, so
> you fallback on yet-another C++ craziness where multiple instantiations of the
> same template type in multiple translation units are collapsed without
creating
> an ODR violation. Put in simple text, if you have a static const int member in
a
> templated class, you must also write the storage for it explicitly via a
partial
> specialization inside the same headerfile, otherwise *sometimes* (often on
weird
> incremental relinks) you will get a link error due to an undefined symbol
(which
> is how I ran in to this...I got a link error).

The defense rests, your honor

https://codereview.chromium.org/2784783003/diff/1/base/trace_event/heap_profi...
File base/trace_event/heap_profiler_allocation_register.h (right):

https://codereview.chromium.org/2784783003/diff/1/base/trace_event/heap_profi...
base/trace_event/heap_profiler_allocation_register.h:82:
std::numeric_limits<decltype(num_inserts_dropped_)>::max()) {
On 2017/03/31 04:28:30, awong wrote:
> On 2017/03/30 13:32:41, Primiano Tucci wrote:
> > I'd make num_inserts_dropped either a bool or a int64 to avoid this extra
> check
> > here.
> > with 64-bit, even if you overflow on each instruction, it would take some
> > thousands year before you actually wrap over (by vaguely remembering intel's
> > argument about making the TSC counter a 64-bit register)
> 
> Is that really necessary?  The branch prediction on this path is gonna be
pretty
> awesome so I don't know what cost we'd be saving on a our common processors?
> 
> If we force 64-bit, then it means in all 32-bit builds, we trade a
> highly-predictable branch for a known 2-instruction operation.

Another battle I don't care enough to respin a discussion. You win also here
(but don't get too used to this pattern :P)

https://codereview.chromium.org/2784783003/diff/1/base/trace_event/heap_profi...
base/trace_event/heap_profiler_allocation_register.h:249:
FixedHashMap<NumBuckets, Key, Value, KeyHasher>::kInvalidKVIndex(-1);
On 2017/03/31 04:28:30, awong wrote:
> On 2017/03/30 13:32:41, Primiano Tucci wrote:
> > I never seen a  -1 more strongly typed than this. :P
> 
> Yeah.... bleh to templates. 
> 
> As noted in chat, we could just replace all this with
> 
> enum { kInvalidIterator = -1 };
> 
> which I did.

Acknowledged. But MSVC didn't like it unfortunately.

https://codereview.chromium.org/2784783003/diff/40001/base/trace_event/heap_p...
File base/trace_event/heap_profiler_allocation_register.cc (right):

https://codereview.chromium.org/2784783003/diff/40001/base/trace_event/heap_p...
base/trace_event/heap_profiler_allocation_register.cc:106: }
minor thing, but  this branch should return true, as the insert technically
succeeded here (by replacing the old entry).

https://codereview.chromium.org/2784783003/diff/40001/base/trace_event/heap_p...
base/trace_event/heap_profiler_allocation_register.cc:163: auto&
backtrace_and_count = backtraces_.Get(index);
I think now you created a bug here.
If you run out of backtraces_ space but not allocations, you can end up with an
allocation which is mapped to backtrace index -1, which will BOOM in the Get
here (tell me again how useless is that guard page now :P).

https://codereview.chromium.org/2784783003/diff/40001/base/trace_event/heap_p...
File base/trace_event/heap_profiler_allocation_register.h (right):

https://codereview.chromium.org/2784783003/diff/40001/base/trace_event/heap_p...
base/trace_event/heap_profiler_allocation_register.h:51: enum { kInvalidKVIndex
= static_cast<KVIndex>(-1) };
unfortunately now we are one bug out and one bug in.
Apparently  this is not enough for MSVC.
See also crbug.com/707288

enum : KVIndex { ...} seems to do the trick

Powered by Google App Engine
This is Rietveld 408576698