I've come to realize the reason why some platforms include a pid of zero in the running process id list, while others don't, is because I incorrectly, and inconsistently, wrote the cross-platform api's for getting all pids, child pids, and parent pid, to include kernel threads on some platforms, while on other platforms, kernel threads are excluded from the list. The solution is not to forcefully prepend a pid of zero to the list when the underlying api omits it, even though this is what we are currently doing. Either include kernel threads or don't.
This means we need to choose which way of doing this we want to support:
- include kernel threads / system-level processes + user-level processes
- user-level processes only
- provide both 1. and 2. but as two separate api's.
What do you think would be the best approach? I'll create a pull request based on what you say.
This is the most portable way of omitting kernel threads, (pseudo-code), because kernel threads have no cmdline or exe path:
struct is_kernel_thread {
bool operator()(ngs_proc_id_t proc_id) {
return (cmdline_from_proc_id(proc_id).empty() && exe_from_proc_id(proc_id).empty());
}
};
vec.erase(std::remove_if(vec.begin(), vec.end(), is_kernel_thread()), vec.end());
As you are probably aware this requires a lot of string allocation and is very slow. There are better ways, but they require a lot more code to implement because it would need platforms specifics not already present in the codebase. For example, NetBSD has the P_SYSTEM flag you can check against the p_flag member of struct kinfo_proc * and that can be used to determine whether a given process id you iterate over is considered a kernel thread or not. Other *BSD's have similar approaches we can take.
I've come to realize the reason why some platforms include a pid of zero in the running process id list, while others don't, is because I incorrectly, and inconsistently, wrote the cross-platform api's for getting all pids, child pids, and parent pid, to include kernel threads on some platforms, while on other platforms, kernel threads are excluded from the list. The solution is not to forcefully prepend a pid of zero to the list when the underlying api omits it, even though this is what we are currently doing. Either include kernel threads or don't.
This means we need to choose which way of doing this we want to support:
What do you think would be the best approach? I'll create a pull request based on what you say.
This is the most portable way of omitting kernel threads, (pseudo-code), because kernel threads have no cmdline or exe path:
As you are probably aware this requires a lot of string allocation and is very slow. There are better ways, but they require a lot more code to implement because it would need platforms specifics not already present in the codebase. For example, NetBSD has the
P_SYSTEMflag you can check against thep_flagmember ofstruct kinfo_proc *and that can be used to determine whether a given process id you iterate over is considered a kernel thread or not. Other*BSD's have similar approaches we can take.