V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
learningman
V2EX  ›  程序员

长期运行的 C 程序遇到 SIGSEGV 错误,如何定位错误发生的位置?

  •  
  •   learningman ·
    Zxilly · 2020-12-27 20:38:31 +08:00 · 3035 次点击
    这是一个创建于 1208 天前的主题,其中的信息可能已经有所发展或是发生改变。
    写了一个程序,长期运行时会遇到 SIGSEGV 错误,但是不知道怎么定位错误位置
    现在是起了一个父进程观察到子进程挂掉就重启,硬抗。
    短时运行不报错,所以没法在开发机上用 gdb 跟踪,编译出来的程序在路由器上跑,同样没法追踪。
    有没有办法做到程序本身输出类似 Python 的 ErrorTrace 呢?
    代码在 https://github.com/Zxilly/UA2F/blob/master/src/ua2f.c
    15 条回复    2020-12-28 09:49:00 +08:00
    AlohaV2
        1
    AlohaV2  
       2020-12-27 20:41:53 +08:00 via iPhone   ❤️ 1
    开启 coredump,还原现场
    lzr325
        2
    lzr325  
       2020-12-27 20:44:41 +08:00 via Android   ❤️ 2
    coredump,backtrace
    learningman
        3
    learningman  
    OP
       2020-12-27 20:52:37 +08:00
    @AlohaV2
    @lzr325 学到了,谢谢二位
    lewis89
        4
    lewis89  
       2020-12-27 22:34:51 +08:00
    @learningman #3 openwrt 上装个 gdb,哈哈 不过我路由器是 x86 内存 CPU 都很大,你如果是 mips 就难了
    lewis89
        5
    lewis89  
       2020-12-27 22:37:21 +08:00
    @learningman #3 用 VPN 吧 这么玩 太折腾人了,而且内核态切换到用户态 开销很大,搞了半天可能还是 VPN 好用
    lewis89
        6
    lewis89  
       2020-12-27 22:41:08 +08:00
    另外为啥不直接弄成 iptables 的内核模块,不过可能 debug 难度比应用态难度要大,应用态还能 coredump
    lewis89
        7
    lewis89  
       2020-12-27 22:46:24 +08:00
    给你 star 了 又了解了一个库 libnetfilter_queue 可以在应用态 定制规则过滤放行 packet
    zeroxia
        8
    zeroxia  
       2020-12-27 22:48:44 +08:00
    如果实在抓不到 coredump 。那么就拼命加 log 吧……
    Hconk
        9
    Hconk  
       2020-12-27 23:43:59 +08:00 via iPhone
    breakpad
    learningman
        10
    learningman  
    OP
       2020-12-28 00:00:59 +08:00
    @lewis89 内核模块崩了整个系统就 boom 了,这样比较安全
    流量不大,只需要清洗出方向流量,这个性能够用了
    no1xsyzy
        11
    no1xsyzy  
       2020-12-28 09:20:20 +08:00
    > 父进程观察到子进程挂掉就重启
    如果你用的是 systemd 的话就自动 coredump 了(
    bfdh
        12
    bfdh  
       2020-12-28 09:24:41 +08:00
    @lewis89 #4 mips 用 GDB 完全没问题,为经常这么干。
    wms
        13
    wms  
       2020-12-28 09:31:21 +08:00   ❤️ 1
    @learningman
    目前看有几个问题, pktb 分配后有好几个地方都直接 return 掉了, 没有释放, 会导致内存泄漏, 这样就会导致 str = malloc() 分配失败, 而 str 没有判断是否分配成功. 另外你可以编译的时候加上-g 标志,我看你段错误的地址是打印出来的, 可以用 addr2line 查看出错的地址. 还有调试内存错误的神器 -fsanitize=address, clang 和 gcc 4.8 以上都支持
    lewis89
        14
    lewis89  
       2020-12-28 09:34:37 +08:00
    @bfdh #12 空间小,125mb ROM 的小米 我都是省着在用,用 x86 之后 我直接在路由器上编译 调试代码了,因为内存跟 CPU 闲置太多了,即使是 J1900 编译 Openwrt 也绰绰有余了
    aneostart173
        15
    aneostart173  
       2020-12-28 09:49:00 +08:00
    我感觉这种情况八成是很小的内存泄漏,最后导致内存分配失败。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5513 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 03:20 · PVG 11:20 · LAX 20:20 · JFK 23:20
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.