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

有没有用过 libmill 的童鞋或者 C 语言大神,求帮忙排查一个段错误的问题

  •  
  •   XiaoxiaoPu · 2016-01-28 11:08:40 +08:00 · 1725 次点击
    这是一个创建于 3011 天前的主题,其中的信息可能已经有所发展或是发生改变。
    代码在这里 https://github.com/XiaoxiaoPu/muon ,功能 README.md 里有写,运行平台是 Linux/OS X 。现在的问题是,重构后使用 libmill 作为协程库,偶尔会出现段错误,有时十几分钟出现一次,有时几个小时出现一次。找了好久没找到问题。希望有大神能帮忙找到问题所在,或提供解决思路,多谢。
    35 条回复    2016-01-29 14:30:46 +08:00
    pagict
        1
    pagict  
       2016-01-28 11:21:24 +08:00   ❤️ 1
    为什么不把 core dump 出来,用调试器看看
    mzer0
        2
    mzer0  
       2016-01-28 11:31:11 +08:00
    你写的加密部分过于惨不忍睹。。。不要自己写加密算法,除非你是读数学的。。。

    你的项目我没看完(代码质量也很惨不忍睹。。。), 先草率地下一个结论。可能你一直都是在 VPS 上跑的, VPS 的核心数不多,因此用 libmill 之前没遇到问题。用 libmill 以后容易产生读写一致性问题,简单地来说要加锁,但是你的程序是单线程设计,除非再重构一次。。。。。。
    airqj
        3
    airqj  
       2016-01-28 11:43:59 +08:00
    这种问题不出点血是没人义务给你解决的
    zhczhy
        4
    zhczhy  
       2016-01-28 11:46:01 +08:00   ❤️ 1
    mark ,晚上 review 下
    XiaoxiaoPu
        5
    XiaoxiaoPu  
    OP
       2016-01-28 11:55:23 +08:00
    @mzer0 加密只是为了混淆,简单就好。 libmill 本身就是单线程、协程,不存在一致性问题。至于你说的代码质量惨不忍睹,能不能具体列举几点?
    XiaoxiaoPu
        6
    XiaoxiaoPu  
    OP
       2016-01-28 12:00:24 +08:00
    @airqj 开源程序,有兴趣就开咯,没兴趣也不强求
    airqj
        7
    airqj  
       2016-01-28 12:07:08 +08:00
    哈哈 还以为是公司用的呢
    抱歉
    hitmanx
        8
    hitmanx  
       2016-01-28 12:38:45 +08:00   ❤️ 1
    菜鸟一枚,晚上看看.core dump 里没啥有用的信息?
    XiaoxiaoPu
        9
    XiaoxiaoPu  
    OP
       2016-01-28 13:04:35 +08:00
    @pagict
    @hitmanx systemd 不知道怎么管理 coredump 的,没找到 coredump ,我再试试吧
    mzer0
        10
    mzer0  
       2016-01-28 14:10:11 +08:00
    @XiaoxiaoPu

    单线程仍然存在一致性问题, 我举个例子, 在 libmill 下, 如果你只有两个线程, 并且执行以下代码:

    线程 A printf("%d",n); printf("%d",++n);
    线程 B printf("%d", n); printf("%d", ++n);

    你看到的输出很可能是: n(线程 A 输出), n(线程 B 输出), n+1(线程 A 输出), n+2(线程 B 输出).

    这里你就会犯一个错误, 你认为 ++n 和 n 总是只差 1, 但实际上不是.
    mzer0
        11
    mzer0  
       2016-01-28 14:15:02 +08:00
    @XiaoxiaoPu

    说句不好听的, 代码质量差主要体现在你把几百行代码能实现的功能写了十几个文件, 并且一点卵用都没有.
    XiaoxiaoPu
        12
    XiaoxiaoPu  
    OP
       2016-01-28 14:19:40 +08:00
    @mzer0 你要知道 libmill 是协程而不是线程,这意味着上下文切换不是任意时刻都会发生的,只有在 libmill 定义的 API 中才可能发生。你真的了解过 libmill 吗?还是主观臆测?
    我认为按照功能把代码划分成文件有助于模块化,你不认同这种思想,那我也没办法。
    Andiry
        13
    Andiry  
       2016-01-28 14:23:00 +08:00   ❤️ 1
    @mzer0 代码质量跟拆成多少个文件有个毛关系?要我说拆的多反而好,一看文件名就知道内容,清楚明了。

    要真说有什么问题,那就是 ifdef 用的太多了, minilzo.c 这个文件简直没法读。
    XiaoxiaoPu
        14
    XiaoxiaoPu  
    OP
       2016-01-28 14:24:03 +08:00
    skydiver
        15
    skydiver  
       2016-01-28 14:25:26 +08:00   ❤️ 1
    @XiaoxiaoPu coredumpctl
    XiaoxiaoPu
        16
    XiaoxiaoPu  
    OP
       2016-01-28 14:25:44 +08:00
    @Andiry minilzo.c 是引用的一个 lzo 压缩库,不是我写的 http://www.oberhumer.com/opensource/lzo/
    mzer0
        17
    mzer0  
       2016-01-28 14:33:25 +08:00
    @XiaoxiaoPu
    @Andiry

    1) 我说的不是文件拆分, 而是你代码本身写得太惨不忍睹, 类似于"说了一堆废话但实际上什么都没做", 本身功能很简单, 几百行代码(可能是三百, 或者两百)就实现了, 你弄了一堆什么用都没有的文件, 还扯上了 libmill......你项目都是建立在 ipconfig 之类的工具之上的, 那还不如直接写个脚本, 压根用不到 C 语言.

    2) 不是我贬低你, 只是你根本不明白一致性问题, 说多了也白说......
    XiaoxiaoPu
        18
    XiaoxiaoPu  
    OP
       2016-01-28 14:43:23 +08:00
    @mzer0 "你项目都是建立在 ipconfig 之类的工具之上的, 那还不如直接写个脚本, 压根用不到 C 语言",呵呵,你拿脚本写一个 ShadowVPN 这样的程序出来啊
    mzer0
        19
    mzer0  
       2016-01-28 14:51:09 +08:00
    @XiaoxiaoPu 那我觉得我们不用继续交谈了, 并且主要原因在我个人看来是你的 C 语言水平过低, 并且无法接受批评.
    XiaoxiaoPu
        20
    XiaoxiaoPu  
    OP
       2016-01-28 14:59:15 +08:00
    @mzer0 “弄了一堆什么用都没有的文件”,那你说说看,哪个文件是多余的没有用的?你说的都是莫名其妙的点,这我肯定无法接受。
    stackpop
        21
    stackpop  
       2016-01-28 15:09:49 +08:00   ❤️ 1
    怎么这也能撕起来.

    楼主同学, 建议你把报错的日志和 coredump 中的栈贴出来. 这样一些有经验的同学可以给你提供些建议, 帮助你 debug.

    v2ex 看到个问题就去搭建环境编译, 还给你重现 core 的人, 应该很难碰到.

    代码风格不算太大问题.
    Andiry
        22
    Andiry  
       2016-01-28 15:10:43 +08:00
    @mzer0 没看出来楼主的代码哪里写的惨不忍睹了,除了莫名其妙的拿拆文件说事以外有没有点干货?贴两段代码论证一下也好啊。
    stackpop
        23
    stackpop  
       2016-01-28 15:12:26 +08:00   ❤️ 1
    把出段错误的上下文, 各种变量, 以及被写坏的变量和地址都 print 出来, 一步步调试, 总能出来.
    stackpop
        24
    stackpop  
       2016-01-28 15:19:02 +08:00
    另外赞一下楼上的"不要自己写加密算法, 除非你是学数学的".... 哈哈, 不知道哪里的自信得出这个结论.
    mzer0
        25
    mzer0  
       2016-01-28 15:19:32 +08:00
    @XiaoxiaoPu 我只能告诉你, 我认为你写得很烂, 1)一部分代码不知道是哪儿抄来的, 2)莫名其妙的宏定义到处都是, 3)糟糕的封装, 4)几乎每一个函数都写得没有丝毫效率可言. 几乎每一个文件都可以被作为"错误编写的 C 语言代码"的范例, 你要我怎么评价? 你自己水平差, 写 C 语言写得少, 就不要拿自己花了很多时间写的糟糕透顶的项目去问别人"你看哪里糟糕了? 我花那么多时间写得我自我感觉挺好啊!".

    自己水平怎样, 自己知道就好了, 想要提高, 就多写点程序, 不要拿到社区上让别人教你怎么写 C 语言, 要有自知之明, 对不对? 你想一想算一算你写过多少个小时的 C 语言程序, 就不要把自己当大师了, 好不好? 不然你等晚上大家下班了, 问问别人怎么评价你写的那个项目, 简直找不到一行写得好的代码......

    不再回复此帖.
    MiguelValentine
        26
    MiguelValentine  
       2016-01-28 15:25:08 +08:00   ❤️ 1
    首先喷人我是不同意的,其次我懒的看 C 。有什么好吵的。 segment 的错误定位还是比较麻烦的- -。
    XiaoxiaoPu
        27
    XiaoxiaoPu  
    OP
       2016-01-28 15:29:59 +08:00
    找到没有 coredump 的原因了,要生成 suid 程序的 coredump ,需要执行 sudo sysctl fs.suid_dumpable=1 才行
    millken
        28
    millken  
       2016-01-28 15:35:46 +08:00
    所以我从不拿代码出来,知道自己会被喷!
    abutter
        29
    abutter  
       2016-01-28 16:19:03 +08:00   ❤️ 1
    coredump 堆栈回溯看一下问题出在哪先。
    kezhuw
        30
    kezhuw  
       2016-01-28 16:28:48 +08:00   ❤️ 1
    @XiaoxiaoPu 如果有多条可能的执行流,单线程仍然有并发问题,这点上 @mzer0 说的没错,“产生读写一致性问题,简单地来说要加锁”。这种情况应该叫 “重入” ?

    你可以看看你的 `heartbeat` 以及 `udp_sender` 函数,`msleep` 和 `udpsend` 这两个地方都可能 yield 掉。多个 `udp_sender` 可能在 `encapsulate` 和 `memcpy` 这里产生 “一致性问题”,当然,这得看 `encapsulate` 做了些什么。不过,这应该可以说明问题了。

    段错误的话,你可以试下 https://github.com/google/sanitizers/wiki/AddressSanitizer
    XiaoxiaoPu
        31
    XiaoxiaoPu  
    OP
       2016-01-28 16:58:38 +08:00
    @kezhuw 非常感谢,我试试。我理解的,重入时如果只修改局部变量,那么不会有问题,这样可能问题在于 minilzo 在压缩时访问全局变量了,我在看下。再次感谢!
    zhczhy
        32
    zhczhy  
       2016-01-28 21:22:32 +08:00   ❤️ 1
    @XiaoxiaoPu
    1. "minilzo.c" 这个是你自己写的还是从其他地方弄来的,这么多宏定义真的挺让人捉急
    2. 你的代码规范性太差,基本的变量声明式初始化都没有。
    3. 多数函数不要写成 static
    4. vpn.c 文件中下面的宏定义改成 const 。
    // 判断一个包是否重复
    #define DUP_LEN 4093

    你先把代码写规范吧,不然有些地方看起来真是困难。
    XiaoxiaoPu
        33
    XiaoxiaoPu  
    OP
       2016-01-28 21:35:53 +08:00
    @zhczhy
    1. http://www.oberhumer.com/opensource/lzo/
    2. 很多变量紧接着就被赋值了,感觉没必要声明时就初始化。除此之外还有哪里规范性太差呢?
    3. 只在本文件用到的函数为什么不写成 static ,万一跟其他文件的符号重名了怎么办?
    4. DUP_LEN 是要作为数组长度的,改成 const 的话 gcc 会编译不通过
    abutter
        34
    abutter  
       2016-01-29 13:20:35 +08:00
    @XiaoxiaoPu lzo 线程安全吗?
    XiaoxiaoPu
        35
    XiaoxiaoPu  
    OP
       2016-01-29 14:30:46 +08:00
    @abutter lzo 是线程安全的,问题已解决,与 lzo 无关。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1015 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 19:41 · PVG 03:41 · LAX 12:41 · JFK 15:41
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.