implement thread enumeration
This commit is contained in:
parent
1f8d733548
commit
0e018fc6c8
3 changed files with 72 additions and 2 deletions
|
|
@ -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
|
||||||
19
src/main.c
19
src/main.c
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue