implement thread enumeration

This commit is contained in:
mykola2312 2024-07-20 22:56:45 +03:00
parent 1f8d733548
commit 0e018fc6c8
3 changed files with 72 additions and 2 deletions

View file

@ -38,9 +38,12 @@ int process_parse_status(pid_t pid, process_status_t* status);
// deallocate list with free later // deallocate list with free later
int processes_by_name(const char* name, process_status_t** list, size_t* count); int processes_by_name(const char* name, process_status_t** list, size_t* count);
// will determine parent process amongst children and set parent pointer to element in list // determine parent process amongst children and set parent pointer to element in list
// process list must consist of parent and children processes, // process list must consist of parent and children processes,
// obtained from processes_by_name call. of course parent pointer shouldn't be NULL // obtained from processes_by_name call. of course parent pointer shouldn't be NULL
int determine_parent_process(process_status_t* list, size_t count, process_status_t** parent); int determine_parent_process(process_status_t* list, size_t count, process_status_t** parent);
// get all process threads. for list and count same rules applies as for processes_by_name
int process_get_threads(pid_t pid, process_status_t** list, size_t* count);
#endif #endif

View file

@ -23,17 +23,34 @@ int main(int argc, char** argv)
process_status_t* list = NULL; process_status_t* list = NULL;
size_t count = 0; size_t count = 0;
// find process
processes_by_name("dummy_target", &list, &count); processes_by_name("dummy_target", &list, &count);
// get real parent
process_status_t* parent; process_status_t* parent;
if (determine_parent_process(list, count, &parent)) if (determine_parent_process(list, count, &parent))
{ {
fputs("unable to determine parent process. exiting", stderr); fputs("unable to determine parent process. exiting\n", stderr);
free(list); free(list);
return 1; return 1;
} }
print_process(parent); print_process(parent);
// get threads
process_status_t* threads = NULL;
size_t thread_count = 0;
if (process_get_threads(parent->pid, &threads, &thread_count))
{
fputs("failed to obtain process threads\n", stderr);
free(list); free(list);
return 1;
}
puts("Threads:");
for (size_t i = 0; i < thread_count; i++)
print_process(&threads[i]);
free(list);
free(threads);
return 0; return 0;
} }

View file

@ -137,3 +137,53 @@ int determine_parent_process(process_status_t* list, size_t count, process_statu
return 1; return 1;
} }
int process_get_threads(pid_t pid, process_status_t** list, size_t* count)
{
char taskPath[256] = {0};
snprintf(taskPath, sizeof(taskPath), "/proc/%d/task", pid);
DIR* taskDir = opendir(taskPath);
if (!taskDir) return 1;
struct dirent* entry;
while ((entry = readdir(taskDir)))
{
if (entry->d_type != DT_DIR) continue;
if (!is_numeric(entry->d_name)) continue;
pid_t pid = strtod(entry->d_name, NULL);
process_status_t status = {};
if (process_parse_status(pid, &status))
{
// if we can't some threads, we should fail completely
// failure is better than incomplete info
TRACE("failed to parse %d task status\n", pid);
closedir(taskDir);
return 1;
}
// add thread to list
process_status_t* _list = *list;
size_t _count = *count;
if (_count) _list = (process_status_t*)realloc(_list, ++_count * sizeof(process_status_t));
else _list = (process_status_t*)malloc(++_count * sizeof(process_status_t));
if (!_list)
{
TRACE("out of memory for process status!\n");
closedir(taskDir);
return 1;
}
// copy thread to list
memcpy(&_list[_count - 1], &status, sizeof(process_status_t));
*list = _list;
*count = _count;
}
closedir(taskDir);
return 0;
}