@@ -241,6 +241,26 @@ class ThreadLocalContextStorage : public RuntimeContextStorage
241241 {
242242 friend class ThreadLocalContextStorage ;
243243
244+ /* *
245+ * Limit the max stack depth.
246+ * The stack will still work beyond this limit,
247+ * counting push() and pop() properly,
248+ * but will not record contexts.
249+ *
250+ * In practice, this should not affect instrumented applications,
251+ * the limit is set to 1 million nested scopes.
252+ *
253+ * The whole reason for this limit to exist is to prevent
254+ * compiler warnings like:
255+ * error: argument 1 value ‘18446744073709551615’
256+ * exceeds maximum object size 9223372036854775807
257+ * [-Werror=alloc-size-larger-than=]
258+ * on this line of code:
259+ * Context *temp = new Context[new_capacity];
260+ * when compiling with gcc and optimizations (-flto).
261+ */
262+ static constexpr size_t max_capacity_ = 1000000 ;
263+
244264 Stack () noexcept : size_(0 ), capacity_(0 ), base_(nullptr ) {}
245265
246266 // Pops the top Context off the stack.
@@ -250,6 +270,11 @@ class ThreadLocalContextStorage : public RuntimeContextStorage
250270 {
251271 return ;
252272 }
273+ if (size_ > max_capacity_)
274+ {
275+ size_ -= 1 ;
276+ return ;
277+ }
253278 // Store empty Context before decrementing `size`, to ensure
254279 // the shared_ptr object (if stored in prev context object ) are released.
255280 // The stack is not resized, and the unused memory would be reutilised
@@ -278,6 +303,10 @@ class ThreadLocalContextStorage : public RuntimeContextStorage
278303 {
279304 return Context ();
280305 }
306+ if (size_ > max_capacity_)
307+ {
308+ return Context ();
309+ }
281310 return base_[size_ - 1 ];
282311 }
283312
@@ -286,6 +315,10 @@ class ThreadLocalContextStorage : public RuntimeContextStorage
286315 void Push (const Context &context) noexcept
287316 {
288317 size_++;
318+ if (size_ > max_capacity_)
319+ {
320+ return ;
321+ }
289322 if (size_ > capacity_)
290323 {
291324 Resize (size_ * 2 );
@@ -299,8 +332,14 @@ class ThreadLocalContextStorage : public RuntimeContextStorage
299332 size_t old_size = size_ - 1 ;
300333 if (new_capacity == 0 )
301334 {
335+ // First increase
302336 new_capacity = 2 ;
303337 }
338+ if (new_capacity > max_capacity_)
339+ {
340+ // Last increase
341+ new_capacity = max_capacity_;
342+ }
304343 Context *temp = new Context[new_capacity];
305344 if (base_ != nullptr )
306345 {
0 commit comments