diff --git a/lib/procinfo.cpp b/lib/procinfo.cpp index 8834723ebc..96d2bc8ca2 100644 --- a/lib/procinfo.cpp +++ b/lib/procinfo.cpp @@ -100,6 +100,25 @@ void find_children(PROC_MAP& pm) { int parentid = i->second.parentid; PROC_MAP::iterator j = pm.find(parentid); if (j == pm.end()) continue; // should never happen +#ifdef _WIN32 + // In Windows: + // 1) PIDs are reused, possibly quickly + // 2) if a process creates children and then exits, + // the parentID of the children are not cleared, + // so they may soon refer to an unrelated process. + // (this is horrible design, BTW) + // This can cause problems: + // - when we abort a BOINC app we kill the process and its descendants + // (based on parent ID). These could be unrelated processes. + // - If a BOINC app gets a process ID that is the parentID of + // orphan processes, its CPU time will be computed incorrectly. + // To fix this, don't create a parent/child link + // if the parent was created after the child. + // + if (j->second.create_time.QuadPart > i->second.create_time.QuadPart) { + continue; + } +#endif j->second.children.push_back(i->first); } } diff --git a/lib/procinfo.h b/lib/procinfo.h index 8112475d17..d283c7cb55 100644 --- a/lib/procinfo.h +++ b/lib/procinfo.h @@ -35,9 +35,11 @@ struct PROCINFO { // running at or below priority of BOINC apps char command[256]; bool scanned; - double page_fault_rate; // derived by higher-level code std::vector children; +#ifdef _WIN32 + LARGE_INTEGER create_time; +#endif PROCINFO() { clear(); diff --git a/lib/procinfo_win.cpp b/lib/procinfo_win.cpp index a86726cee4..c4f4c4ba20 100644 --- a/lib/procinfo_win.cpp +++ b/lib/procinfo_win.cpp @@ -97,6 +97,7 @@ int get_procinfo_XP(PROC_MAP& pm) { p.user_time = ((double) pProcesses->UserTime.QuadPart)/1e7; p.kernel_time = ((double) pProcesses->KernelTime.QuadPart)/1e7; p.is_low_priority = (pProcesses->BasePriority <= 4); + p.create_time = pProcesses->CreateTime; WideCharToMultiByte(CP_ACP, 0, pProcesses->ProcessName.Buffer, pProcesses->ProcessName.Length,