添加进程访问函数
This commit is contained in:
parent
af5c96ec2e
commit
fbca5468f1
|
@ -186,13 +186,14 @@ namespace sys_util
|
||||||
}
|
}
|
||||||
typedef struct _enum_proc_cb
|
typedef struct _enum_proc_cb
|
||||||
{
|
{
|
||||||
|
bool process;
|
||||||
bool(*on_found)(uint64_t pid, const char* path_name, void* param);
|
bool(*on_found)(uint64_t pid, const char* path_name, void* param);
|
||||||
void* param;
|
void* param;
|
||||||
}ENPROCCB, * LPENPROCCB;
|
}ENPROCCB, * LPENPROCCB;
|
||||||
static bool found_process(const char* path, bool is_dir, void* param)
|
static bool found_process(const char* path, bool is_dir, void* param)
|
||||||
{
|
{
|
||||||
LPENPROCCB cb = (LPENPROCCB)param;
|
LPENPROCCB cb = (LPENPROCCB)param;
|
||||||
const char* id = strstr(path + 2, "/");
|
const char* id = strrchr(path, '/');
|
||||||
uint64_t pid = 0;
|
uint64_t pid = 0;
|
||||||
std::string path_name("");
|
std::string path_name("");
|
||||||
|
|
||||||
|
@ -212,9 +213,37 @@ namespace sys_util
|
||||||
if (*id)
|
if (*id)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
if (cb->process)
|
||||||
|
{
|
||||||
path_name = get_module_path(nullptr, pid);
|
path_name = get_module_path(nullptr, pid);
|
||||||
|
id = path_name.c_str();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// get start address of pid to path_name
|
||||||
|
id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
return cb->on_found(pid, path_name.c_str(), cb->param);
|
return cb->on_found(pid, id, cb->param);
|
||||||
|
}
|
||||||
|
static bool on_stack_line_read(char* line, void* param)
|
||||||
|
{
|
||||||
|
LPENPROCCB cb = (LPENPROCCB)param;
|
||||||
|
std::string m(line);
|
||||||
|
uint64_t off = 0;
|
||||||
|
size_t pos = m.find("]");
|
||||||
|
|
||||||
|
if (pos++ != std::string::npos)
|
||||||
|
m.erase(0, pos);
|
||||||
|
trim_left(m);
|
||||||
|
pos = m.find("+0x");
|
||||||
|
if (pos != std::string::npos)
|
||||||
|
{
|
||||||
|
off = from_hex_str(m.c_str() + pos + 3);
|
||||||
|
m.erase(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
return cb->on_found(off, m.c_str(), cb->param);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t enum_modules(bool(*on_found)(const char* path_module_name, bool is_dir, void* param),// return false to stop enumeratin
|
int32_t enum_modules(bool(*on_found)(const char* path_module_name, bool is_dir, void* param),// return false to stop enumeratin
|
||||||
|
@ -283,9 +312,53 @@ namespace sys_util
|
||||||
|
|
||||||
cb.on_found = on_found;
|
cb.on_found = on_found;
|
||||||
cb.param = param;
|
cb.param = param;
|
||||||
|
cb.process = true;
|
||||||
|
|
||||||
return enum_files("/proc", found_process, &cb, false);
|
return enum_files("/proc", found_process, &cb, false);
|
||||||
}
|
}
|
||||||
|
uint32_t enum_threads(uint64_t pid, bool(*on_found)(uint64_t tid, void* start_addr, void* param), void* param)
|
||||||
|
{
|
||||||
|
ENPROCCB cb;
|
||||||
|
|
||||||
|
cb.process = false;
|
||||||
|
cb.param = param;
|
||||||
|
*(void**)&cb.on_found = *(void**)&on_found;
|
||||||
|
|
||||||
|
return enum_files(("/proc/" + std::to_string(pid) + "/task").c_str(), found_process, &cb, false);
|
||||||
|
}
|
||||||
|
uint32_t get_thread_callstack(uint64_t pid, uint64_t tid, bool(*on_found)(uint64_t off, const char* module, void* param), void* param)
|
||||||
|
{
|
||||||
|
ENPROCCB cb;
|
||||||
|
|
||||||
|
cb.process = false;
|
||||||
|
cb.param = param;
|
||||||
|
*(void**)&cb.on_found = *(void**)&on_found;
|
||||||
|
|
||||||
|
return read_line(("/proc/" + std::to_string(pid) + "/task/" + std::to_string(tid) + "/stack").c_str(), on_stack_line_read, &cb);
|
||||||
|
}
|
||||||
|
uint32_t read_line(const char* file, bool(*on_line)(char* line, void* param), void* param)
|
||||||
|
{
|
||||||
|
FILE* src = fopen(file, "rb");
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
if (!src)
|
||||||
|
return errno;
|
||||||
|
|
||||||
|
size_t ll = 1024;
|
||||||
|
char* line = new char[ll];
|
||||||
|
while (fgets(line, ll - 1, src))
|
||||||
|
{
|
||||||
|
if (!on_line(line, param))
|
||||||
|
break;
|
||||||
|
|
||||||
|
memset(line, 0, ll);
|
||||||
|
}
|
||||||
|
err = errno;
|
||||||
|
delete[] line;
|
||||||
|
fclose(src);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
std::string get_module_path(const char* module_name, unsigned pid) // get module full path, nullptr is for main-exe
|
std::string get_module_path(const char* module_name, unsigned pid) // get module full path, nullptr is for main-exe
|
||||||
{
|
{
|
||||||
|
@ -435,5 +508,83 @@ namespace sys_util
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool is_char_in(const char* str, char ch)
|
||||||
|
{
|
||||||
|
if (ch == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
while (*str)
|
||||||
|
{
|
||||||
|
if (*str++ == ch)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool trim_left(std::string& str, const char* space)
|
||||||
|
{
|
||||||
|
int off = 0;
|
||||||
|
|
||||||
|
for (; off < str.length(); ++off)
|
||||||
|
{
|
||||||
|
if (!is_char_in(space, str[off]))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (off)
|
||||||
|
str.erase(0, off);
|
||||||
|
|
||||||
|
return off > 0;
|
||||||
|
}
|
||||||
|
bool trim_right(std::string& str, const char* space)
|
||||||
|
{
|
||||||
|
int off = str.length() - 1;
|
||||||
|
|
||||||
|
for (; off >= 0; --off)
|
||||||
|
{
|
||||||
|
if (!is_char_in(space, str[off]))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (off < str.length() - 1)
|
||||||
|
{
|
||||||
|
str.erase(off + 1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
uint64_t from_hex_str(const char* hex, const char** end)
|
||||||
|
{
|
||||||
|
uint64_t val = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < 16; ++i)
|
||||||
|
{
|
||||||
|
if (*hex >= '0' && *hex <= '9')
|
||||||
|
{
|
||||||
|
val <<= 4;
|
||||||
|
val += *hex - '0';
|
||||||
|
}
|
||||||
|
else if (*hex >= 'a' && *hex <= 'f')
|
||||||
|
{
|
||||||
|
val <<= 4;
|
||||||
|
val += *hex - 'a' + 10;
|
||||||
|
}
|
||||||
|
else if (*hex >= 'A' && *hex <= 'F')
|
||||||
|
{
|
||||||
|
val <<= 4;
|
||||||
|
val += *hex - 'A' + 10;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
hex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (end)
|
||||||
|
*end = hex;
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -123,6 +123,9 @@ namespace sys_util
|
||||||
, bool recursive = true // walk recursive
|
, bool recursive = true // walk recursive
|
||||||
); // return errno
|
); // return errno
|
||||||
int32_t enum_processes(bool(*on_found)(uint64_t pid, const char* path_name, void* param), void* param);
|
int32_t enum_processes(bool(*on_found)(uint64_t pid, const char* path_name, void* param), void* param);
|
||||||
|
uint32_t enum_threads(uint64_t pid, bool(*on_found)(uint64_t tid, void* start_addr, void* param), void* param);
|
||||||
|
uint32_t get_thread_callstack(uint64_t pid, uint64_t tid, bool(*on_found)(uint64_t off, const char* module, void* param), void* param);
|
||||||
|
uint32_t read_line(const char* file, bool(*on_line)(char* line, void* param), void* param);
|
||||||
|
|
||||||
std::string get_module_path(const char* module_name = nullptr
|
std::string get_module_path(const char* module_name = nullptr
|
||||||
, unsigned pid = -1); // get module full path, nullptr is for main-exe
|
, unsigned pid = -1); // get module full path, nullptr is for main-exe
|
||||||
|
@ -165,4 +168,9 @@ namespace sys_util
|
||||||
int32_t get_memory_info(uint64_t* total, uint64_t* available);
|
int32_t get_memory_info(uint64_t* total, uint64_t* available);
|
||||||
std::string format_readable_bytes(uint64_t bytes); // convert to readable text: 512B, 1.21KB, 1.10MB, 3.45GB, 1,234.56GB ...
|
std::string format_readable_bytes(uint64_t bytes); // convert to readable text: 512B, 1.21KB, 1.10MB, 3.45GB, 1,234.56GB ...
|
||||||
std::string get_command_output(const char* cmd, uint16_t max_line_len = 256, bool one_line = true);
|
std::string get_command_output(const char* cmd, uint16_t max_line_len = 256, bool one_line = true);
|
||||||
|
|
||||||
|
// trim string, return whether space trimmed
|
||||||
|
bool trim_left(std::string& str, const char* space = " \t");
|
||||||
|
bool trim_right(std::string& str, const char* space = " \t");
|
||||||
|
uint64_t from_hex_str(const char* hex, const char** end = nullptr); // convert 0x100 to 256. parameter 'end' to receive the stopped position
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,8 +10,104 @@
|
||||||
#include "scanner.h"
|
#include "scanner.h"
|
||||||
|
|
||||||
|
|
||||||
|
static bool found_proc(uint64_t pid, const char* path, void* param)
|
||||||
|
{
|
||||||
|
uint32_t* cnt = (uint32_t*)param;
|
||||||
|
|
||||||
|
printf("%d - %ld: %s\n", ++cnt[0], pid, path);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
static bool found_modules(const char* path, bool is_dir, void* param)
|
||||||
|
{
|
||||||
|
uint32_t* cnt = (uint32_t*)param;
|
||||||
|
|
||||||
|
printf("%d - %s\n", ++cnt[0], path);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
static bool found_modules_norepeat(const char* path, bool is_dir, void* param)
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32_t cnt;
|
||||||
|
std::vector<std::string> modules;
|
||||||
|
}*data = nullptr;
|
||||||
|
|
||||||
|
*(void**)&data = param;
|
||||||
|
|
||||||
|
if (std::find(data->modules.begin(), data->modules.end(), path) == data->modules.end())
|
||||||
|
{
|
||||||
|
printf("%d - %s\n", ++data->cnt, path);
|
||||||
|
data->modules.push_back(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
static bool on_found_thread(uint64_t tid, void* start_addr, void* param)
|
||||||
|
{
|
||||||
|
uint32_t* cnt = (uint32_t*)param;
|
||||||
|
|
||||||
|
printf("%d - %p(%u): starting at %p\n", ++cnt[0], tid, tid, start_addr);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
static bool on_stack(uint64_t off, const char* module, void* param)
|
||||||
|
{
|
||||||
|
uint32_t* cnt = (uint32_t*)param;
|
||||||
|
|
||||||
|
printf("%d - %s + %p\n", ++cnt[0], module, off);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t main(int32_t argc, char *argv[])
|
int32_t main(int32_t argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
// uint32_t cnt = 0, err = 0;
|
||||||
|
//
|
||||||
|
// if(argc >= 2)
|
||||||
|
// {
|
||||||
|
// if(strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "-?") == 0 || strcmp(argv[1], "-help") == 0)
|
||||||
|
// {
|
||||||
|
// printf("usage: proc - no options, to enum all processes\n\
|
||||||
|
// -?/-h/-help: to show this message\n\
|
||||||
|
// <pid> [-nrp], to enum process(pid) modules, '-nrp' do not print repeating modules\n\
|
||||||
|
// <-t pid> [tid], to enum threads or print callstack of given thread\
|
||||||
|
// ");
|
||||||
|
// }
|
||||||
|
// else if(argc >= 3)
|
||||||
|
// {
|
||||||
|
// if(strcmp(argv[1], "-t") == 0)
|
||||||
|
// {
|
||||||
|
// uint32_t pid = atoi(argv[2]);
|
||||||
|
// if(argc >= 4)
|
||||||
|
// err = sys_util::get_thread_callstack(pid, atoi(argv[3]), on_stack, &cnt);
|
||||||
|
// else
|
||||||
|
// err = sys_util::enum_threads(pid, on_found_thread, &cnt);
|
||||||
|
// }
|
||||||
|
// else if(strcmp(argv[2], "-nrp") == 0)
|
||||||
|
// {
|
||||||
|
// struct
|
||||||
|
// {
|
||||||
|
// uint32_t cnt = 0;
|
||||||
|
// std::vector<std::string> modules;
|
||||||
|
// }data;
|
||||||
|
// err = sys_util::enum_modules(found_modules_norepeat, &data, atoi(argv[1]));
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// err = sys_util::enum_modules(found_modules, &cnt, atoi(argv[1]));
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// err = sys_util::enum_processes(found_proc, &cnt);
|
||||||
|
// }
|
||||||
|
// if(err)
|
||||||
|
// printf("error = %d (%s)\n", err, strerror(err));EINVAL;
|
||||||
|
//
|
||||||
|
// return 0;
|
||||||
|
|
||||||
|
|
||||||
char *oper = argc > 1 ? argv[1] : nullptr;
|
char *oper = argc > 1 ? argv[1] : nullptr;
|
||||||
|
|
||||||
log_cls::initialize(nullptr);
|
log_cls::initialize(nullptr);
|
||||||
|
|
Loading…
Reference in New Issue