@@ -591,20 +591,12 @@ func (pm *ProcessManager) SynchronizeProcess(pr process.Process) {
591
591
return
592
592
}
593
593
if len (mappings ) == 0 {
594
- // Valid process without any (executable) mappings. All cases are
595
- // handled as process exit. Possible causes and reasoning:
596
- // 1. It is a kernel worker process. The eBPF does not send events from these,
597
- // but we can see kernel threads here during startup when tracer walks
598
- // /proc and tries to synchronize all PIDs it sees.
599
- // The PID should not exist anywhere, but we can still double check and
600
- // make sure the PID is not tracked.
601
- // 2. It is a normal process executing, but we just sampled it when the kernel
602
- // execve() is rebuilding the mappings and nothing is currently mapped.
603
- // In this case we can handle it as process exit because everything about
604
- // the process is changing: all mappings, comm, etc. If execve fails, we
605
- // reaped it early. If execve succeeds, we will get new synchronization
606
- // request soon, and handle it as a new process event.
607
- pm .processPIDExit (pid )
594
+ // TODO: Check if main thread has exited, e.g. /proc/PID/stat will show zombie
595
+ log .Warnf ("%v: main thread exit" , pid )
596
+ pm .mu .Lock ()
597
+ defer pm .mu .Unlock ()
598
+ pm .pidMainThreadExit [pid ] = libpf.Void {}
599
+ pm .ebpf .RemoveReportedPID (pid )
608
600
return
609
601
}
610
602
@@ -630,23 +622,33 @@ func (pm *ProcessManager) SynchronizeProcess(pr process.Process) {
630
622
631
623
// CleanupPIDs executes a periodic synchronization of pidToProcessInfo table with system processes.
632
624
// NOTE: Exported only for tracer.
633
- func (pm * ProcessManager ) CleanupPIDs () {
625
+ func (pm * ProcessManager ) CleanupPIDs (fast bool ) {
634
626
deadPids := make ([]libpf.PID , 0 , 16 )
635
-
636
627
pm .mu .RLock ()
637
- for pid := range pm .pidToProcessInfo {
628
+ defer func () {
629
+ pm .mu .RUnlock ()
630
+ for _ , pid := range deadPids {
631
+ pm .processPIDExit (pid )
632
+ }
633
+ if len (deadPids ) > 0 {
634
+ log .Debugf ("Cleaned up %d dead PIDs" , len (deadPids ))
635
+ }
636
+ }()
637
+
638
+ log .Warnf ("Fast cleanup" )
639
+ for pid := range pm .pidMainThreadExit {
638
640
if live , _ := proc .IsPIDLive (pid ); ! live {
639
641
deadPids = append (deadPids , pid )
640
642
}
641
643
}
642
- pm .mu .RUnlock ()
643
-
644
- for _ , pid := range deadPids {
645
- pm .processPIDExit (pid )
644
+ if fast {
645
+ return
646
646
}
647
-
648
- if len (deadPids ) > 0 {
649
- log .Debugf ("Cleaned up %d dead PIDs" , len (deadPids ))
647
+ log .Warnf ("Slow cleanup" )
648
+ for pid := range pm .pidToProcessInfo {
649
+ if live , _ := proc .IsPIDLive (pid ); ! live {
650
+ deadPids = append (deadPids , pid )
651
+ }
650
652
}
651
653
}
652
654
@@ -707,6 +709,10 @@ func (pm *ProcessManager) ProcessedUntil(traceCaptureKTime times.KTime) {
707
709
}
708
710
709
711
delete (pm .pidToProcessInfo , pid )
712
+ if _ , ok := pm .pidMainThreadExit [pid ]; ok {
713
+ delete (pm .pidMainThreadExit , pid )
714
+ log .Warnf ("%v: cleanup" , pid )
715
+ }
710
716
711
717
for _ , instance := range pm .interpreters [pid ] {
712
718
if err2 := instance .Detach (pm .ebpf , pid ); err2 != nil {
0 commit comments