forked from RobotLocomotion/drake
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlimit_malloc.h
82 lines (71 loc) · 2.82 KB
/
limit_malloc.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#pragma once
namespace drake {
namespace test {
/// Parameters to control malloc limits.
struct LimitMallocParams {
/// Maximum calls to malloc, calloc, or realloc (totaled as one).
/// When less than zero, there is no limit on the number of calls.
int max_num_allocations{-1};
/// Minimum calls to malloc, calloc, or realloc (totaled as one).
/// When less than zero, there is no limit on the number of calls.
int min_num_allocations{-1};
/// Whether a realloc() that leaves its `ptr` unchanged should be ignored.
bool ignore_realloc_noops{false};
};
/// Instantiate this class in a unit test scope where malloc (and realloc,
/// etc.) should be disallowed or curtailed.
///
/// @note This class is currently a no-op in some build configurations:
/// - macOS
/// - leak sanitizer
/// - valgrind tools
///
/// Example:
/// @code
/// GTEST_TEST(LimitMallocTest, BasicTest) {
/// std::vector<double> foo(100); // Heap allocation is OK.
/// {
/// LimitMalloc guard;
/// // The guarded code goes here. Heap allocations result in aborts.
/// std::array<double, 100> stack;
/// }
/// std::vector<double> bar(100); // Heap allocation is OK again.
/// }
/// @endcode
///
/// Currently, when the device under test violates its allocation limits, the
/// test terminates with an abort(). To better isolate what went wrong, re-run
/// the test in a debugger.
///
/// This class is only intended for use in test code. To temporarily use it in
/// non-test code, hack the BUILD.bazel file to mark this library `testonly = 0`
/// instead of `testonly = 1`.
class LimitMalloc final {
public:
/// Applies malloc limits until this object's destructor is run.
/// All allocations will fail.
/// For now, only *one* instance of this class may be created at a time.
/// (In the future, we may allow updating the limits by nesting these guards.)
LimitMalloc();
/// Applies malloc limits until this object's destructor is run.
/// A allocations will succeed except for any limits designated in args.
/// For now, only *one* instance of this class may be created at a time.
/// (In the future, we may allow updating the limits by nesting these guards.)
explicit LimitMalloc(LimitMallocParams args);
/// Undoes this object's malloc limits.
~LimitMalloc();
/// Returns the number of allocations observed so far.
int num_allocations() const;
/// Returns the parameters structure used to construct this object.
const LimitMallocParams& params() const;
// We write this out by hand, to avoid depending on Drake *at all*.
/// @name Does not allow copy, move, or assignment
//@{
LimitMalloc(const LimitMalloc&) = delete;
void operator=(const LimitMalloc&) = delete;
LimitMalloc(LimitMalloc&&) = delete;
void operator=(LimitMalloc&&) = delete;
//@}
};
} // namespace test
} // namespace drake