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

Unified Diff: base/timer/timer_unittest.cc

Issue 2624133004: Fix use-after-free in base::Timer::StopAndAbandon() (Closed)
Patch Set: Merge branch 'master' into timer_bug Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « base/timer/timer.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/timer/timer_unittest.cc
diff --git a/base/timer/timer_unittest.cc b/base/timer/timer_unittest.cc
index 7c3c1079d72f54be9585287c4ace5473c9c7b5f2..69338eb211b52c32e0bc31250c515597c30d02ca 100644
--- a/base/timer/timer_unittest.cc
+++ b/base/timer/timer_unittest.cc
@@ -13,6 +13,7 @@
#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
+#include "base/memory/ref_counted.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/sequenced_task_runner.h"
@@ -556,6 +557,50 @@ TEST(TimerTest, MessageLoopShutdown) {
EXPECT_FALSE(did_run.IsSignaled());
}
+// Ref counted class which owns a Timer. The class passes a reference to itself
+// via the |user_task| parameter in Timer::Start(). |Timer::user_task_| might
+// end up holding the last reference to the class.
+class OneShotSelfOwningTimerTester
+ : public RefCounted<OneShotSelfOwningTimerTester> {
+ public:
+ OneShotSelfOwningTimerTester() = default;
+
+ void StartTimer() {
+ // Start timer with long delay in order to test the timer getting destroyed
+ // while a timer task is still pending.
+ timer_.Start(FROM_HERE, TimeDelta::FromDays(1),
+ base::Bind(&OneShotSelfOwningTimerTester::Run, this));
+ }
+
+ private:
+ friend class RefCounted<OneShotSelfOwningTimerTester>;
+ ~OneShotSelfOwningTimerTester() = default;
+
+ void Run() {
+ ADD_FAILURE() << "Timer unexpectedly fired.";
+ }
+
+ OneShotTimer timer_;
+
+ DISALLOW_COPY_AND_ASSIGN(OneShotSelfOwningTimerTester);
+};
+
+TEST(TimerTest, MessageLoopShutdownSelfOwningTimer) {
+ // This test verifies that shutdown of the message loop does not cause crashes
+ // if there is a pending timer not yet fired and |Timer::user_task_| owns the
+ // timer. The test may only trigger exceptions if debug heap checking is
+ // enabled.
+
+ MessageLoop loop;
+ scoped_refptr<OneShotSelfOwningTimerTester> tester =
+ new OneShotSelfOwningTimerTester();
+
+ std::move(tester)->StartTimer();
+ // |Timer::user_task_| owns sole reference to |tester|.
+
+ // MessageLoop destructs by falling out of scope. SHOULD NOT CRASH.
+}
+
void TimerTestCallback() {
}
« no previous file with comments | « base/timer/timer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698