You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ubuntu编译的二进制在Alpine中调用duplocale()触发段错误的解决办法

问题:Ubuntu编译的二进制在Alpine中调用duplocale()触发段错误

问题重现

在Ubuntu 22.04上编译以下C代码:

#include <locale.h>
#include <stdio.h>

int main() {
        printf("1\n");
        locale_t oldlocale = uselocale(NULL);
        printf("2\n");
        locale_t duploc = duplocale(oldlocale);
        printf("3\n");
        return 0;
}

Ubuntu上运行正常:

$ gcc -g c.c && ./a.out 
1
2
3

但将二进制复制到Alpine容器中运行时,调用duplocale()触发段错误:

# ./a.out 
1
2
Segmentation fault (core dumped)

环境说明

已在Alpine容器中安装libc6-compat等兼容组件,且该代码在Alpine本地编译可正常运行,但实际场景无法采用本地编译方式。问题源于依赖的libjson-c调用duplocale()导致段错误,即使动态链接Alpine版本的json-c也无法解决。

调试信息

Alpine中的调试输出

process 340 is executing new program: /lib/ld-musl-x86_64.so.1
1
2

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7f46aa7 in ?? ()
(gdb) bt
#0  0x00007ffff7f46aa7 in ?? ()
#1  0x0000000000000001 in ?? ()
#2  0x00007ffff7f521cd in ?? ()
#3  0xffffffffffffffff in ?? ()
#4  0x00007ffff7fc1600 in __libc_start_init () at ldso/dynlink.c:1621
#5  0x00007ffff7f786d1 in libc_start_main_stage2 (main=0x7ffff7f52189, argc=-1, argv=0x7fffffffebb0)
    at src/env/__libc_start_main.c:95
#6  0x00007ffff7f520c5 in ?? ()
#7  0x00007fffffffebf8 in ?? ()
#8  0x00007ffff7f520a0 in ?? ()
#9  0x0000000000000001 in ?? ()
#10 0x00007fffffffee50 in ?? ()
#11 0x0000000000000000 in ?? ()

带回Ubuntu调试core文件的输出

Core was generated by `ld-linux-x86-64.so.2 --argv0 ./a.out --preload /lib/libgcompat.so.0  -- /dm/res'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x00007f1c76999aa7 in ?? ()
(gdb) bt
#0  0x00007f1c76999aa7 in ?? ()
#1  0x0000000000000001 in ?? ()
#2  0x00007f1c769a51cd in ?? ()
#3  0xffffffffffffffff in ?? ()
#4  0x00007f1c76a0e600 in ?? ()
#5  0x00007ffc8621ad98 in ?? ()
#6  0x00007f1c769c56d1 in ?? ()
#7  0x0000000000000000 in ?? ()

注:二进制保留调试信息,未被剥离。

关键线索

json-c的CMakeLists.txt中提到:

# uClibc *intentionally* crashes in duplocale(), at least as of:
# https://github.com/ffainelli/uClibc/blob/266bdc1/libc/misc/locale/locale.c#L1322
# So, if it looks like we're compiling for a system like that just disable
# locale handling entirely.

可行解决办法

  • 禁用json-c的locale支持:若能重新编译依赖的json-c,添加编译选项-DENABLE_LOCALES=OFF,让json-c跳过locale相关逻辑,避免调用duplocale()。
  • Hook替换duplocale函数:通过LD_PRELOAD加载自定义共享库,替换duplocale的实现。示例代码:
    #define _GNU_SOURCE
    #include <locale.h>
    #include <dlfcn.h>
    
    locale_t duplocale(locale_t loc) {
        // 直接返回传入的locale,不执行复制操作(需注意线程安全)
        return loc;
    }
    
    编译为共享库:gcc -shared -fPIC hook_duplocale.c -o libhook_duplocale.so,运行时加载:LD_PRELOAD=./libhook_duplocale.so ./your_binary
  • 静态链接glibc:在Ubuntu编译时添加-static选项静态链接glibc,让二进制不依赖Alpine的musl libc,但会增大体积,且可能带来其他兼容性问题。
  • 更换运行容器:若业务允许,直接使用Ubuntu容器运行,规避libc兼容问题。

内容的提问来源于stack exchange,提问作者hudac

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 03:15:07