添加进程访问函数
This commit is contained in:
parent
af5c96ec2e
commit
fbca5468f1
|
@ -186,13 +186,14 @@ namespace sys_util
|
|||
}
|
||||
typedef struct _enum_proc_cb
|
||||
{
|
||||
bool process;
|
||||
bool(*on_found)(uint64_t pid, const char* path_name, void* param);
|
||||
void* param;
|
||||
}ENPROCCB, * LPENPROCCB;
|
||||
static bool found_process(const char* path, bool is_dir, void* param)
|
||||
{
|
||||
LPENPROCCB cb = (LPENPROCCB)param;
|
||||
const char* id = strstr(path + 2, "/");
|
||||
const char* id = strrchr(path, '/');
|
||||
uint64_t pid = 0;
|
||||
std::string path_name("");
|
||||
|
||||
|
@ -212,9 +213,37 @@ namespace sys_util
|
|||
if (*id)
|
||||
return true;
|
||||
|
||||
if (cb->process)
|
||||
{
|
||||
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
|
||||
|
@ -283,9 +312,53 @@ namespace sys_util
|
|||
|
||||
cb.on_found = on_found;
|
||||
cb.param = param;
|
||||
cb.process = true;
|
||||
|
||||
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
|
||||
{
|
||||
|
@ -435,5 +508,83 @@ namespace sys_util
|
|||
|
||||
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
|
||||
); // return errno
|
||||
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
|
||||
, 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);
|
||||
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);
|
||||
|
||||
// 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"
|
||||
|
||||
|
||||
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[])
|
||||
{
|
||||
// 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;
|
||||
|
||||
log_cls::initialize(nullptr);
|
||||
|
|
Loading…
Reference in New Issue