跳至主要内容

libunwind查看其他进程的堆栈

 g++ -g3 -o main main.cpp -std=c++11 -lunwind -lunwind-x86_64 -lunwind-ptrace

 

#include <iostream>
#include <libunwind.h>
#include <libunwind-ptrace.h>
#include <unistd.h>
#include <sys/ptrace.h>
#include <sys/wait.h>
#include <cxxabi.h>
#include <cstdio>

int wait4stop(pid_t pid) {
    int status = 99;
    do {
        if (waitpid(pid, &status, 0) == -1 || WIFEXITED(status) || WIFSIGNALED(status))
            return 0;
    } while(!WIFSTOPPED(status));
    return 1;
}

void get_backtrace(pid_t pid) {
    unw_cursor_t cursor, resume_cursor;
    unw_context_t context;
    unw_word_t ip, sp, off;

    unw_addr_space_t addr_space = unw_create_addr_space(&_UPT_accessors, __BYTE_ORDER__);
    if (!addr_space) 
        std::cerr << "Failed to create address space" << std::endl;

    unw_getcontext(&context);

    if (-1 == ptrace(PTRACE_ATTACH, pid, nullptr, nullptr))
        std::cerr << "Failed to ptrace" << std::endl;

    if (!wait4stop(pid))
        std::cerr << "wait SIGSTOP of ptrace failed" << std::endl;

    void *rctx = _UPT_create(pid);

    if (rctx == nullptr) 
        std::cerr << "Failed to _UPT_create" << std::endl;

    if (unw_init_remote(&cursor, addr_space, rctx))
        std::cerr << "unw_init_remote failed" << std::endl;

    resume_cursor = cursor;

    const size_t bufflen = 256;
    char *buff = new char[bufflen];

    do {
        char *name = "23333";
        unw_get_reg(&cursor, UNW_REG_IP, &ip);
        unw_get_reg(&cursor, UNW_REG_SP, &sp);

        // 获取函数名字
        if (0 == unw_get_proc_name(&cursor, buff, bufflen, &off)) {
            int status = 99;
            printf("%s---", buff);
            // 如果符号表中没有找到buff的函数名
            if ((name = abi::__cxa_demangle(buff, nullptr, nullptr, &status)) == 0)
                name = buff;
        }
        printf("%s.\n", name);
    } while (unw_step(&cursor) > 0);

    delete[] buff;
    _UPT_resume(addr_space, &resume_cursor, rctx);
    _UPT_destroy(rctx);

    // 然后是将进程结束中断
    ptrace(PTRACE_DETACH, pid, nullptr, nullptr);
}

int main(int argc, char **argv) {
    if (argc < 2) 
        std::cerr << "please input pid" << std::endl;

    pid_t pid = std::atoi(argv[1]);
    get_backtrace(pid);
    return 0;
} 
 
 
 

评论

此博客中的热门博文

ncurses与readline结合

  #define _XOPEN_SOURCE 700       /* for wcswidth and 700 is for mbsnrtowcs */ #include<wchar.h> #include<ncurses.h>       /* ncurses.h includes stdio.h */ #include<stdlib.h> #include<string.h> #include<readline/readline.h> #include<locale.h>     int mygetstr( char *str, int y, int x){    WINDOW *win;    int size, col;    int ok = 0;    int width;    wchar_t wstr[80];    char *p;        getmaxyx(stdscr, size, col);        void getaline( char *s){      str = s;      rl_callback_handler_remove();      ok = 1;    }        rl_callback_handler_install( "" , getaline);    win = newwin(1, col-x, y, x);    while (1){      rl_callback_read_char(); ...

简单的整数最小乘积的解法

给定 n 个整数,每次可以从剩下的整数中取走两个整数并计算这两个整数的积。 若该操作进行 m 次,求每次计算的积之和的最小值。 Input / 输入格式 有多组测试数据。第一行输入一个整数 T(约 30)代表测试数据组数,对于每组数据: 第一行输入两个整数 n 和 m(1≤n≤10​5​​, 0≤m≤​2​​n​​),它们的含义如题中所述。 第二行输入 n 个整数 a​1​​,a​2​​,⋯,a​n​​(0≤a​i​​≤10​4​​)表示给定的整数。 Output / 输出格式 每组数据输出一行一个整数,表示积之和的最小值。 Sample Input / 样例输入 3 4 2 1 3 2 4 3 1 2 3 1 4 0 1 3 2 4 Sample Output / 样例输出 10 2 0   Hint / 样例说明 对于第一组样例数据,答案是 1×4+3×2=10。 对于第二组样例数据,答案是 2×1=2。 package main import (         "bufio"         "fmt"         "os"         "sort"         "strconv"         "strings" ) var ...

老毛子路由器无线桥接问题

  信道带宽:改成20M  关闭 DHCP 服务器  关闭动态 (DHCP) 路由 修改IP地址从192.168.123.1到192.168.1.114  无线 AP 工作模式:选择AP-Client+AP 无线 AP-Client 角色:选择LAN bridge 连上上级wifi done 路由器自身可能上不去网,执行: route add default  gw 192.168.1.1 不过这种方式无法翻墙 ////////////////////////////////////////////////////////////// 第二种方式 不改信道不关闭DHCP,保持网段是192.168.123.1 无线 AP 工作模式:选择AP-Client+AP 无线 AP-Client 角色:选择WAN 连上上级wifi done 路由器可以翻墙,但是192.168.1.1的机器访问不了192.168.123.1的机器 解决方法: 在192.168.123.1的机器把想要访问的机器比如192.168.123.100设置DMZ主机,这样就可以访问了,在 192.168.1.1能看到分配的ip比如192.168.1.115