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

C++ Modules执行触发std::bad_alloc核心转储,请求排查原因

问题描述

源代码

hello.cpp

module;

import <filesystem>;
import <iostream>;

export module hello;

export void fun()
{
        std::cout << "Hello, GCC " << __GNUC__ << '.' << __GNUC_MINOR__ << '.' << __GNUC_PATCHLEVEL__ << '!' << std::endl;
        std::cout << "Hello, CXX " << __cplusplus << '!' << std::endl;
        std::cout << "PWD: " << std::filesystem::current_path() << std::endl;
}

main.cpp

import hello;

int main()
{
        fun();
        return 0;
}

运行平台

  • 操作系统:Linux
  • 发行版:Ubuntu 22.04.2 LTS
  • 架构:x86_64 & aarch64(均已测试)
  • GCC版本:11.3.0 & 14.0.0(均已测试)

编译命令

g++-14 -std=c++23 -fmodules-ts -Wall -Wextra -pedantic -c -x c++-system-header filesystem iostream
g++-14 -std=c++23 -fmodules-ts -Wall -Wextra -pedantic hello.cpp main.cpp -o module-test-g++-14

g++-11 -std=c++23 -fmodules-ts -Wall -Wextra -pedantic -c -x c++-system-header filesystem iostream
g++-11 -std=c++23 -fmodules-ts -Wall -Wextra -pedantic hello.cpp main.cpp -o module-test-g++-11

执行结果

不同架构和GCC版本下结果类似,均出现核心转储问题。

user@host:~/tmp$ ./module-test-g++-14 
Hello, GCC 14.0.0!
Hello, CXX 202302!
terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc
Aborted (core dumped)

user@host:~/tmp$ ./module-test-g++-11 
Hello, GCC 11.3.0!
Hello, CXX 202100!
terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc
Aborted (core dumped)

调试信息

问题源于内部内存分配失败:

(gdb) 
298           _M_get_allocator() const
(gdb) 
std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::max_size (this=0x7fffffffdf40) at /usr/include/c++/11/bits/basic_string.h:932
932           { return (_Alloc_traits::max_size(_M_get_allocator()) - 1) / 2; }
(gdb) 

std::allocator_traits<std::allocator<char> >::max_size (__a=...) at /usr/include/c++/11/bits/alloc_traits.h:552
552             return size_t(-1) / sizeof(value_type);
(gdb) 
547           max_size(const allocator_type& __a __attribute__((__unused__))) noexcept
(gdb) 
std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::max_size (this=0x7fffffffdf40) at /usr/include/c++/11/bits/basic_string.h:932
932           { return (_Alloc_traits::max_size(_M_get_allocator()) - 1) / 2; }
(gdb) 
931           max_size() const _GLIBCXX_NOEXCEPT
(gdb) 
std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_create (this=0x7fffffffdf40, __capacity=@0x7fffffffddd0: 93824992338720, __old_capacity=0) at /usr/include/c++/11/bits/basic_string.tcc:137
137           if (__capacity > max_size())
(gdb) 
143           if (__capacity > __old_capacity && __capacity < 2 * __old_capacity)
(gdb) 
153           return _Alloc_traits::allocate(_M_get_allocator(), __capacity + 1);
(gdb) 
std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_get_allocator (this=0x7fffffffdf40) at /usr/include/c++/11/bits/basic_string.h:295
295           { return _M_dataplus; }
(gdb) 
294           _M_get_allocator()
(gdb) 
std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_create (this=0x7fffffffdf40, __capacity=@0x7fffffffddd0: 93824992338720, __old_capacity=0) at /usr/include/c++/11/bits/basic_string.tcc:153
153           return _Alloc_traits::allocate(_M_get_allocator(), __capacity + 1);
(gdb) 
std::allocator_traits<std::allocator<char> >::allocate (__a=..., __n=93824992338721) at /usr/include/c++/11/bits/alloc_traits.h:464
464           { return __a.allocate(__n); }
(gdb) 
std::allocator<char>::allocate (__n=93824992338721, this=0x7fffffffdf40) at /usr/include/c++/11/bits/allocator.h:182
182             if (std::is_constant_evaluated())
(gdb) 
std::is_constant_evaluated () at /usr/include/c++/11/type_traits:3419
3419      { return __builtin_is_constant_evaluated(); }
(gdb) 
3418      is_constant_evaluated() noexcept
(gdb) 
std::allocator<char>::allocate (__n=93824992338721, this=0x7fffffffdf40) at /usr/include/c++/11/bits/allocator.h:182
182             if (std::is_constant_evaluated())
(gdb) 
185             return __allocator_base<_Tp>::allocate(__n, 0);
(gdb) 
__gnu_cxx::new_allocator<char>::allocate (this=0x7fffffffdf40, __n=93824992338721) at /usr/include/c++/11/ext/new_allocator.h:111
111             if (__builtin_expect(__n > this->_M_max_size(), false))
(gdb) 
__gnu_cxx::new_allocator<char>::_M_max_size (this=0x7fffffffdf40) at /usr/include/c++/11/ext/new_allocator.h:200
200             return std::size_t(__PTRDIFF_MAX__) / sizeof(_Tp);
(gdb) 
197           _M_max_size() const _GLIBCXX_USE_NOEXCEPT
(gdb) 
__gnu_cxx::new_allocator<char>::allocate (this=0x7fffffffdf40, __n=93824992338721) at /usr/include/c++/11/ext/new_allocator.h:111
111             if (__builtin_expect(__n > this->_M_max_size(), false))
(gdb) 
127             return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp)));
(gdb) 
terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc

Program received signal SIGABRT, Aborted.
__pthread_kill_implementation (no_tid=0, signo=6, threadid=140737348187968) at ./nptl/pthread_kill.c:44
44      ./nptl/pthread_kill.c: No such file or directory.

问询

编译命令是否存在错误?或者这是GCC的bug?

  • 若为个人问题,请告知正确编译方式。
  • 若为GCC的bug,将向官方提交报告。

解答

这是GCC在C++模块TS支持中的已知bug,根源在于std::filesystem的全局状态在模块模式下未正确初始化,导致current_path()返回的std::string内部出现非法的超大容量值,触发std::bad_alloc异常。

临时修复方案

  1. 切换为传统头文件包含方式:将模块中的import <filesystem>;替换为#include <filesystem>,移除模块前缀module;,转为普通C++代码编译(不再使用-fmodules-ts参数)。
  2. 手动触发初始化:在调用current_path()前,显式调用std::filesystem::path::codecvt()强制初始化相关全局状态。修改后的fun()函数如下:
    export void fun()
    {
            std::cout << "Hello, GCC " << __GNUC__ << '.' << __GNUC_MINOR__ << '.' << __GNUC_PATCHLEVEL__ << '!' << std::endl;
            std::cout << "Hello, CXX " << __cplusplus << '!' << std::endl;
            // 手动触发filesystem全局状态初始化
            (void)std::filesystem::path::codecvt();
            std::cout << "PWD: " << std::filesystem::current_path() << std::endl;
    }
    

bug提交建议

该问题在GCC 11到14版本中均存在,属于模块TS与标准库组件的兼容性问题。提交bug时附上测试代码、编译命令、运行环境及调试信息,可帮助开发者快速定位问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 03:43:09