V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
huahsiung
V2EX  ›  Linux

项目从 Ubuntu 移植到 Debian 出现莫名其妙的 bug。

  •  
  •   huahsiung · 2023-10-17 22:21:51 +08:00 · 3657 次点击
    这是一个创建于 408 天前的主题,其中的信息可能已经有所发展或是发生改变。

    项目是半年前上线的,一共留下了有两个版本。Linux ( Ubuntu 下 gcc 编译) Windows (本地测试版本,vs 编译的)。

    然后项目跑的 docker 里面的。

    最近迁移服务器,换了一个 host OS(从 Ubuntu 换到 Debian)。因为是 docker ,除了内核嘛,其他都差不多。想都没想,直接 docker save ---> docker load ,扔过去。

    然后在 Debian host OS 上,发现没启动。于是尝试手动启动,发现启动大概 1s 后,Segmentation fault 错误。


    然后以为程序有 bug ,找了半天,真的找到了一个 bug 。修改测试,还是报 Segmentation fault 。大概不是这个 bug 引起的。 然后我想,之前服务器顶住 bug 跑了半年都没出事。怎么可能迁移就出事。这个 bug 应该不是致命错误。于是又改回去。

    .

    从早上九点忙到晚上 10 点,本来准备 2h 就完成的,但是出现莫名其妙的 bug ,虽然给了半个月迁移的时间

    期间莫名其妙的比对过 md5sum ,一模一样!,但是就是无法在新的 Debian host 上运行。而老 Ubuntu 顶住 bug 跑也正常。没办法,找不到,项目又要迁移。


    然后到晚上了。心好累啊,就破罐破摔。能上线就不错了,哪里要求这么多啊,就把 Windows 下的版本制作为一个 docker 版本的 wine 。然后把 Windows 版的程序扔到 wine 镜像里面,测试了一下,卧。槽,卧。槽!!!完全正常,没任何问题!!。

    上线了。!!

    想了想,唯一的区别就算内核了,我不知道是不是 Ubuntu 的内核什么不同。 虽然现在不是生产环境。但是如果 wine 没出错。半个月后主服务器就会迁移,或许就会变成生产环境了。

    . .

    安装以前的规律,只要没出错,根本没人注意到 wine 。就算出错了,一般也是 docker restart 。

    虽然如此明显。但是也依然不会有人注意。

    用 wine 跑项目感觉特别危险。没办法,哎,孤立无援啊。现在只有我接手前任代码后,一个人在维护。里面指针看上去就是到处乱飞。

    希望下一个接手的人不要炸掉。


    感觉只有两个可能:

    1.Debian Linux 内核版本比 Ubuntu 高。

    2.Ubuntu 内核问题。Ubuntu 自动把 bug 优化了???


    希望以后不要看到这样的的帖子:“生产环境出现重大事故,项目竟然用 wine 跑了快 1 年”。

    因为迁移本来就算没的。算莫名其妙来的“义务”吧。

    wine 解决方案完美,唯一缺点就是容器多了 1G 空间占用。

    第 1 条附言  ·  2023-10-17 23:48:56 +08:00
    虚拟机粗略测试 Debian 10 ( 4.19 内核),正常使用。Ubuntu 是 18.04.6 LTS 。可能是内核版本高的原因( Debian 11 )。

    另外,docker 里面,glibc 应该是一样的。不存在环境问题。
    大概是内核问题。程序里面指针太乱了,纯粹乱飞。

    gdb 显示似乎是 malloc()没申请到???,然后读取到未定义的内存??。但是看代码,判断了 apply_mem !=NULL 的。如果没申请到,会提示并退出的。

    原因未知,出现玄学问题。
    43 条回复    2023-10-25 18:52:21 +08:00
    mikewang
        1
    mikewang  
       2023-10-17 22:34:18 +08:00
    程序和人,有一个能跑就行?
    ferock
        2
    ferock  
       2023-10-17 22:43:03 +08:00 via Android
    所以,论 docker 沙盒的重要性
    zedpass
        3
    zedpass  
       2023-10-17 22:51:40 +08:00
    先把 Debian 装上和 Ubuntu 一样的 Docker 版本再试下
    Achilless
        4
    Achilless  
       2023-10-17 22:51:59 +08:00
    docker 版本一样吗
    nightwitch
        5
    nightwitch  
       2023-10-17 23:09:29 +08:00
    Segmentation fault 错误首先怀疑 libc 和 libstdc++的问题吧。
    wqtacc
        6
    wqtacc  
       2023-10-17 23:09:40 +08:00   ❤️ 1
    能重新再 debian 下编译打包吗
    virusdefender
        7
    virusdefender  
       2023-10-17 23:10:52 +08:00
    至少先 gdb 下啊
    cnbatch
        8
    cnbatch  
       2023-10-17 23:22:40 +08:00
    针对这个程序,建议专门用 Debian 做开发测试,说不定更容易找得到真正的 bug
    bjzhush
        9
    bjzhush  
       2023-10-17 23:36:49 +08:00
    碉堡了
    我从来没想过 wine 还能跑在服务器上
    之前是非常排斥 wine 的,觉得这玩意就是杂交,非要把 win 下的东西搞到 Linux 上跑,用了十几年 Ubuntu 从来不 wine
    ysc3839
        10
    ysc3839  
       2023-10-18 00:14:12 +08:00 via Android
    遇到了 undefined behavior 吧,各种因素影响之下,发生什么都是有可能的。
    @bjzhush 也不奇怪,还有在服务器上用 WSL 或者 MSYS2 的,就是损失一些性能而已。
    huahsiung
        11
    huahsiung  
    OP
       2023-10-18 00:14:40 +08:00
    再说一下,本地 Debian ( GUI xfce )运行并无 bug ,但是到服务器上面就有 bug 了。

    wine 能跑就行,反正只是项目的一个组件。并不是全部项目
    SupperMary
        12
    SupperMary  
       2023-10-18 00:22:20 +08:00
    让我想起来我编译 AOSP13 的代码,死活编译不过,搞了快一个星期,最后把 kernel 从 6.x 降到 5.x 编译过了
    LitterGopher
        13
    LitterGopher  
       2023-10-18 00:46:51 +08:00
    已经能想到后面的人接手是什么心情了,哈哈哈哈和。
    kkk9
        14
    kkk9  
       2023-10-18 01:50:59 +08:00
    搞个 debian 虚拟机直接调试看看结果?
    fpk5
        15
    fpk5  
       2023-10-18 03:43:54 +08:00
    内核不一样很难说,可能是内核编译参数不一样导致行为不一样也有可能是在 ubuntu 能跑纯粹是运气。
    sadfQED2
        16
    sadfQED2  
       2023-10-18 07:18:47 +08:00 via Android   ❤️ 4
    卧槽,wine 跑线上服务,这能震惊我一整天
    kaiveyoung
        17
    kaiveyoung  
       2023-10-18 07:50:41 +08:00 via Android
    之前有个项目,换了个平台段错误,debug 了好几个小时,发现是有个 int 函数没 return ,未定义行为真的会在不同平台触发不同的异常
    ho121
        18
    ho121  
       2023-10-18 07:58:06 +08:00 via Android
    段错误,大概率是 c 或 c++写的吧。
    c 或 c++有一些写法会产生未定义的行为,比如指针之间做加减运算。不同平台处理方式不一样。
    tramm
        19
    tramm  
       2023-10-18 08:05:23 +08:00
    Docker 版本多少
    lrh3321
        20
    lrh3321  
       2023-10-18 08:05:44 +08:00
    CPU 型号也一致?之前试过编译 dpdk 程序,默认按编译机器的指令集来构建。
    tairan2006
        21
    tairan2006  
       2023-10-18 08:48:59 +08:00
    你用 Debian 重新编译一下
    nuk
        22
    nuk  
       2023-10-18 08:55:47 +08:00
    我记得 docker 是可以用 kvm 的?
    pubby
        23
    pubby  
       2023-10-18 09:06:28 +08:00 via iPhone
    遇到过 ubuntu 某个版本制作的 docker image 在某几个 k8s 节点一启动就 segfault
    go 静态编译的程序

    换 ubuntu 其他版本重新制作就正常了
    LonnyWong
        24
    LonnyWong  
       2023-10-18 09:07:55 +08:00
    这题我懂,大概率是某个变量没初始化。在能运行的环境碰巧是 0 ,相当于初始化了。在不能运行的环境,碰巧不是 0 ,然后它又是个指针之类,就段错误了。在不同的环境,大概率每次运行都是相同的结果,要么总是成功,要么总是出错,例外的情况是少数。
    LonnyWong
        25
    LonnyWong  
       2023-10-18 09:12:14 +08:00
    这题我懂,大概率是某个变量没初始化。在能运行的环境碰巧是 0 ,相当于初始化了。在不能运行的环境,碰巧不是 0 ,然后它又是个指针之类,就段错误了。在相同的环境,大概率每次运行都是相同的结果,要么总是成功,要么总是出错,例外的情况是少数。
    LonnyWong
        26
    LonnyWong  
       2023-10-18 09:15:26 +08:00 via iPhone
    忽略 #24 ,打错了一个字。
    huahsiung
        27
    huahsiung  
    OP
       2023-10-18 09:32:02 +08:00
    粗略调试,发现可能有两个代码块有问题。

    一个是记录时间的

    char timebuf[256];
    time_t time1;
    struct tm *time2;
    time(&time1);
    time2=localtime(&time1);
    memcpy(timebuf,asctime(time2),256);
    strtok(timebuf, "\n");
    shijingshijing
        28
    shijingshijing  
       2023-10-18 09:33:22 +08:00
    从 Debian 迁移到 Ubuntu 大概率不会出什么问题,反之估计会有各种妖蛾子,查下依赖库吧,有可能是 Ubuntu 用了更高版本的某个 libxxx.so
    huahsiung
        29
    huahsiung  
    OP
       2023-10-18 09:39:59 +08:00
    还有一个是用 char 数组 ipaddr[40];直接存 IP 地址。
    struct epoll_event c_Event;

    ...

    int fd;
    struct sockaddr_in apply_addr;
    struct sockaddr_in6 apply_addr6;
    const int addrlen=sizeof(apply_addr6);
    char ipaddr[40];
    memset(&apply_addr6,0,sizeof(struct sockaddr_in6));
    fd = accept(evfd, (struct sockaddr *)&apply_addr6, &addrlen);
    logtime_func(....) //这个是调用前面记录时间函数的。


    大概看到这里,程序到这里会异常。


    也可能不是这个原因,因为这里其他平台都不异常,无法复现。虽然编译器每次都警告。
    huahsiung
        30
    huahsiung  
    OP
       2023-10-18 09:44:13 +08:00
    @huahsiung
    补充:

    int fd;
    struct sockaddr_in apply_addr;
    struct sockaddr_in6 apply_addr6;
    const int addrlen=sizeof(apply_addr6);
    char ipaddr[40];
    memset(&apply_addr6,0,sizeof(struct sockaddr_in6));
    fd = accept(evfd, (struct sockaddr *)&apply_addr6, &addrlen);
    logtime_func(....) //这个是调用前面记录时间函数的。


    inet_ntop(AF_INET6,&(apply_addr6.sin6_addr),&ipaddr,40);

    char ipv4buf[16];
    memcpy(ipv4buf,ipaddr+7,16);
    strcpy(ipaddr,ipv4buf);



    另外 docker 里面的 libxxx.so 应该是一样的。应该不是依赖库问题
    huahsiung
        31
    huahsiung  
    OP
       2023-10-18 09:49:40 +08:00
    启动大概 1s 后,出现 Segmentation fault 错误。

    确认是有 tcp 连接进来后才出现的。因为其他组件连接超时重试设置的一般也是 1s
    ryanking8215
        32
    ryanking8215  
       2023-10-18 09:54:34 +08:00   ❤️ 1
    编译器警告贴一下呢?
    addrlen 在 accept 里是 in/out 类型的参数,为啥定义成 const 呢?
    ttvast
        33
    ttvast  
       2023-10-18 10:36:21 +08:00
    Segmentation fault 没有 core dump 吗?
    LokiSharp
        34
    LokiSharp  
       2023-10-18 10:45:24 +08:00
    不要用 Ubuntu 编译
    huahsiung
        35
    huahsiung  
    OP
       2023-10-18 11:15:36 +08:00
    @ryanking8215

    后续,不是这里代码问题。绕过该代码依然报错。
    差点把 wine 也弄崩了。


    世上本无事,庸人自扰之。

    现在已经跑起来了,还是不要自找麻烦了。万一两边都崩了才麻烦。
    ttvast
        36
    ttvast  
       2023-10-18 11:16:09 +08:00
    会不会两个服务器一个配置了 ipv6 ,一个禁用了 ipv6
    swulling
        37
    swulling  
       2023-10-18 11:16:18 +08:00 via iPhone
    容器不隔离内核,所以可能是内核的问题。
    swulling
        38
    swulling  
       2023-10-18 11:16:51 +08:00 via iPhone
    core dump 下看看
    pooorguy
        39
    pooorguy  
       2023-10-18 11:51:56 +08:00 via Android
    @sadfQED2

    "我原本以为用 livecd 跑服务已经天下无敌了,
    没想到有人用 wine 比他还勇猛,

    这是谁的部将!"



    ----三国大魏集团 CEO 曹操
    realpg
        40
    realpg  
       2023-10-18 11:59:26 +08:00
    @bjzhush #9
    当你的必须供应商给你一个只有.net 1.1 可以调用的 dll 文件
    我就 wine 写过一个封装转成本机服务
    tomychen
        41
    tomychen  
       2023-10-18 12:06:06 +08:00
    整个过程,让我看得触目惊心

    心情久久不能平静

    Segmentation fault 后,居然不是拉 log ,gdb / coredump ,而是直接切 wine...

    并且换发行,居然没过渡,直接上。

    硬核,硬核
    heelerdeer
        42
    heelerdeer  
       2023-10-18 15:16:32 +08:00
    op 能用 gdb 调试一下吗?看看报错信息,有可能是因为低版本编译器的一些 bug
    Xunit
        43
    Xunit  
       2023-10-25 18:52:21 +08:00
    @SupperMary aosp 编译的那个 bug 我也遇到了,编译到最后明明还有很多内存但就是分配不出,然后就直接退出了,不过其他的内核(比如 zen ,xanmod 都提前修复了)
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2878 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 12:27 · PVG 20:27 · LAX 04:27 · JFK 07:27
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.