summaryrefslogtreecommitdiffhomepage
path: root/pkg
diff options
context:
space:
mode:
authorDean Deng <deandeng@google.com>2021-04-19 16:43:20 -0700
committergVisor bot <gvisor-bot@google.com>2021-04-19 16:48:27 -0700
commit20b1c3c632277bd64eac4d0442bda9695f184fc9 (patch)
treeb2627fb84af14531bffed6dec381e4cd76867533 /pkg
parent7bfc76d946b6c3f02fc32831ddc282ac2816d5ed (diff)
Move runsc reference leak checking to better locations.
In the previous spot, there was a roughly 50% chance that leak checking would actually run. Move it to the waitContainer() call on the root container, where it is guaranteed to run before the sandbox process is terminated. Add it to runsc/cli/main.go as well for good measure, in case the sandbox exit path does not involve waitContainer(). PiperOrigin-RevId: 369329796
Diffstat (limited to 'pkg')
-rw-r--r--pkg/refsvfs2/refs_map.go25
1 files changed, 16 insertions, 9 deletions
diff --git a/pkg/refsvfs2/refs_map.go b/pkg/refsvfs2/refs_map.go
index 0472eca3f..fb8984dd6 100644
--- a/pkg/refsvfs2/refs_map.go
+++ b/pkg/refsvfs2/refs_map.go
@@ -112,20 +112,27 @@ func logEvent(obj CheckedObject, msg string) {
log.Infof("[%s %p] %s:\n%s", obj.RefType(), obj, msg, refs_vfs1.FormatStack(refs_vfs1.RecordStack()))
}
+// checkOnce makes sure that leak checking is only done once. DoLeakCheck is
+// called from multiple places (which may overlap) to cover different sandbox
+// exit scenarios.
+var checkOnce sync.Once
+
// DoLeakCheck iterates through the live object map and logs a message for each
// object. It is called once no reference-counted objects should be reachable
// anymore, at which point anything left in the map is considered a leak.
func DoLeakCheck() {
if leakCheckEnabled() {
- liveObjectsMu.Lock()
- defer liveObjectsMu.Unlock()
- leaked := len(liveObjects)
- if leaked > 0 {
- msg := fmt.Sprintf("Leak checking detected %d leaked objects:\n", leaked)
- for obj := range liveObjects {
- msg += obj.LeakMessage() + "\n"
+ checkOnce.Do(func() {
+ liveObjectsMu.Lock()
+ defer liveObjectsMu.Unlock()
+ leaked := len(liveObjects)
+ if leaked > 0 {
+ msg := fmt.Sprintf("Leak checking detected %d leaked objects:\n", leaked)
+ for obj := range liveObjects {
+ msg += obj.LeakMessage() + "\n"
+ }
+ log.Warningf(msg)
}
- log.Warningf(msg)
- }
+ })
}
}