diff --git a/pkg/sentry/fs/proc/task.go b/pkg/sentry/fs/proc/task.go index 70578d3fa..335003dd8 100644 --- a/pkg/sentry/fs/proc/task.go +++ b/pkg/sentry/fs/proc/task.go @@ -461,7 +461,14 @@ func (s *taskStatData) ReadSeqFileData(ctx context.Context, h seqfile.SeqHandle) fmt.Fprintf(&buf, "%d %d ", linux.ClockTFromDuration(cputime.UserTime), linux.ClockTFromDuration(cputime.SysTime)) fmt.Fprintf(&buf, "%d %d ", s.t.Priority(), s.t.Niceness()) fmt.Fprintf(&buf, "%d ", s.t.ThreadGroup().Count()) - fmt.Fprintf(&buf, "0 0 " /* itrealvalue starttime */) + + // itrealvalue. Since kernel 2.6.17, this field is no longer + // maintained, and is hard coded as 0. + fmt.Fprintf(&buf, "0 ") + + // Start time is relative to boot time, expressed in clock ticks. + fmt.Fprintf(&buf, "%d ", linux.ClockTFromDuration(s.t.StartTime().Sub(s.t.Kernel().Timekeeper().BootTime()))) + var vss, rss uint64 s.t.WithMuLocked(func(t *kernel.Task) { if mm := t.MemoryManager(); mm != nil { diff --git a/test/syscalls/linux/proc.cc b/test/syscalls/linux/proc.cc index 0da682e7b..64d75d9fb 100644 --- a/test/syscalls/linux/proc.cc +++ b/test/syscalls/linux/proc.cc @@ -880,6 +880,14 @@ TEST_P(ProcPidStatTest, HasBasicFields) { EXPECT_EQ("R", fields[2]); // task state EXPECT_EQ(absl::StrCat(getppid()), fields[3]); + // If the test starts up quickly, then the process start time and the kernel + // boot time will be very close, and the proc starttime field (which is the + // delta of the two times) will be 0. For that unfortunate reason, we can + // only check that starttime >= 0, and not that it is strictly > 0. + uint64_t starttime; + ASSERT_TRUE(absl::SimpleAtoi(fields[21], &starttime)); + EXPECT_GE(starttime, 0); + uint64_t vss; ASSERT_TRUE(absl::SimpleAtoi(fields[22], &vss)); EXPECT_GT(vss, 0);