【问题标题】:gcc string table overflow error during compilation编译期间gcc字符串表溢出错误
【发布时间】:2013-01-02 15:54:51
【问题描述】:

当我尝试从 boost spirit Qi compiler_tutorial 构建一个大型复杂示例(在模板实例化方面修改为更复杂)时,我收到以下错误消息:

 debug\expression.o:-1: error: section .debug_frame$_ZNK5boost5proto3if_INS0_6detail7has_tagINS0_6tagns_3tag7greaterEEENS0_12reverse_foldINS0_1_ENS0_6_stateENS2_18reverse_fold_tree_IS6_NS_6spirit6detail18make_binary_helperINSC_13meta_compilerINSC_2qi6domainEE12meta_grammarEEEEEEESK_E4implIRNSG_4ruleINSC_3lex7lexertl8iteratorINSR_7functorINSR_14position_tokenIN9__gnu_cxx17__normal_iteratorIPKcSsEENS_3mpl6vectorISsN4mpl_2naES13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_EENS12_5bool_ILb0EEEyEENSR_6detail4dataESZ_NS15_ILb1EEES16_EEEEFSt4listIN7client3ast10expressionIdEESaIS1H_EEvENSC_11unused_typeES1L_S1L_EENS_6fusion4consINSG_12literal_charINSC_13char_encoding8standardELb1ELb0EEENS1O_4nil_EEERS1L_EclES1N_RKS1V_S1W_: string table overflow at offset 10000433

命令行:

c:/mingw64/bin/../libexec/gcc/x86_64-w64-mingw32/4.7.2/cc1plus.exe -quiet -v -I c:/libs/boost/include -I ../src/compiler -I c:/libs/boost/include -I . -I c:/libs/Qt-static/mkspecs/win32-g++-x64-4.7.2-corei7-avx-corei7-avx -iprefix c:\mingw64\bin\../lib/gcc/x86_64-w64-mingw32/4.7.2/ -D_REENTRANT -U_REENTRANT -D BOOST_THREAD_POSIX -D BOOST_THREAD_USE_LIB -D UNICODE -D QT_LARGEFILE_SUPPORT -D _DEBUG=1 -D DEBUG=1 -D BOOST_SPIRIT_QI_DEBUG=1 -D BOOST_SPIRIT_NO_PREDEFINED_TERMINALS=1 ../src/compiler/expression.cpp -quiet -dumpbase expression.cpp -m64 -march=corei7-avx -mtune=corei7-avx -mtls-dialect=gnu2 -auxbase-strip debug/expression.o -g -O0 -Wall -Wextra -std=gnu++11 -version -fsignaling-nans -fno-math-errno -frtti -fexceptions -o - |

平台:mingw-builds (x64-4.7.2-release-posix-sjlj-rev5.7z) 用于 x64 主机和目标 (-m64)(符合 gcc 4.7.2)在 x64 Windows 7 HB 上8GB 物理内存。

看来是内存不够了。

我应该怎么做才能避免这个问题?我确定这里没有递归模板。

【问题讨论】:

  • 尝试删除 -g 选项....
  • gas 在一段时间内消耗了 449 272 kB 的物理内存,然后退出并出现错误。

标签: gcc g++


【解决方案1】:

我发现这个问题的一个答案并不令人满意,但经过进一步研究,确实看起来运行具有更高优化级别的 gcc 是解决这个问题的方法。我想我会分享我学到的东西。

此问题特定于以 PE/COFF 格式编写二进制文件,这是 Windows 使用的。搜了一下binutils的源码,找到this code snippet/comment in bfd's coff backend code

/* An inherent limitation of the /nnnnnnn notation used to indicate
the offset of the long name in the string table is that we
cannot address entries beyone the ten million byte boundary.  */
if (string_size >= 10000000)
{
  bfd_set_error (bfd_error_file_too_big);
  (*_bfd_error_handler)
    (_("%B: section %s: string table overflow at offset %ld"),
    abfd, current->name, string_size);
  return FALSE;
}

二进制中的字符串表看起来在 PE/COFF 中最多可以有 1000 万字节。我相信唯一限制它的是节表条目的格式只为节名指定 8 个字节。如果一个名字比那个长,它可以在字符串表中指定一个偏移量。该数字必须由 UTF-8 编码字符串中的 ASCII 表示,并以正斜杠开头。这只给你七个以 10 为底的数字,因此限制为 10,000,000。我在 Microsoft 的 PE/COFF 规范修订版 8.1 的第 13 节中发现了这一点。

你不能真正改变二进制格式,所以我知道的唯一解决方法是让 gcc 制作一个更小的字符串表。 -O2 帮了我大忙。

【讨论】:

  • 但经过进一步研究,确实似乎运行具有更高优化级别的 gcc 是解决此问题的方法 - 拆分二进制代码如何(即创建多个共享图书馆)?优化级别是减少字符串表的唯一方法吗?
  • 我也有这个问题,-O1 或 -Os 对我有帮助,但对于找出究竟哪些优化可以解决这个问题非常有帮助,所以我尝试使用所有启用的优化 - O1/-Os 令我惊讶的是它不起作用,我尝试了这个 -f 标志的各种组合。总结就是没有找到更好的解决方案,我试了3个小时才找到。
【解决方案2】:

我遇到了类似的问题并找到了解决方案。我使用了很多来自 Boost.Spirit2 解析器的 boost 模板类。

我在 openSuse 12.2 (gcc 4.7.2) 上使用 MingW64 交叉编译器 MingW32 编译相同的文件没有问题,无论是在发布模式下,还是在调试模式下。

命令:

/usr/bin/x86_64-w64-mingw32-g++ -c -fpermissive -fexceptions -Wall -Wextra -Wno-long-long -Wno-unknown-pragmas -mthreads -Wall -frtti -finline-functions -o 文件.o 文件.cpp

输出:

部.pdata $ _ZN5boost6fusion6detail10linear_anyINS0_13cons_iteratorIKNS0_4consINS_6spirit2qi6kleeneINS6_10char_classINS5_3tag9char_codeINS9_5spaceENS5_13char_encoding8standardEEEEEEENS4_INS6_11alternativeINS4_INS6_6actionINSI_INSI_INS6_8sequenceINS4_INSI_INS6_14literal_stringIRA11_KcLb1EEENS_7phoenix5actorINSP_9compositeINSP_6detail13function_evalILi2EEENS0_6vectorINSP_5valueINSP_3stl9push_backEEENSP_9referenceISsEENSW_IcEENS0_5void_ES13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_EEEEEEEENS4_INS6_16lexeme_directiveINS7_INSI_INS6_10differenceINS8_INSA_INS9_5char_ESD_EEEENS6_10eol_parserEEENSQ_INSR_ISU_NSV_ISZ_S11_NS5_8argumentILi0EEES13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_Ssos-夜间@ SUSE-x86-64的:〜/ MNT /约瑟夫/ SUS E / build__mingw64__individual__next__debug / SRC / sos_import> _SF_EEEENS4_ISG_NS0_3nilEEEEEEEEEEENS4_INS6_4plusINSI_INS6_9referenceIKNS6_4ruleIN9__gnu_cxx17__normal_iteratorIPSL_SsEEFN7dynardo9structure11SimplexDataEvENS_5proto7exprns_4exprINS2A_6tagns_3tag8terminalENS2A_7argsns_4termINSA_INS9_5blankESD_EEEELl0EEENS5_11unused_typeES2M_EEEENSQ_INSR_ISU_NSV_INSW_INSS_19member_function_ptrILi1EvM11My_PushbackINS27_20SimplexDataContainerEEFvRKS28_EEEEENSW_IPS2T_EES1G_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_EEEEEEEEEES1T_EEEEEEEEEEEENSQ_INSR_ISU_NSV_INSW_INSX_6insertEEENS10_ISt3mapISsS2S_St4lessISsESaISt4pairIKSsS2S_EEEEENS10_IS3I_ISsS2S_EEES13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_EEEEEEEENSQ_INSR_INST_IL i1EEENSV_INSW_INSX_5clearEEES11_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_EEEEEEEENSQ_INSR_IS3U_NSV_IS3W_NS10_IS2S_EES13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_EEEEEEEENS4_INSI_INSI_INSI_INSJ_INS4_INSK_IRA9_SL_Lb1EEENS4_IS1S_NS4_ISG_S37_EEEEEEEES3S_EES3Z_EES44_EENS4_INSJ_IS1V_EES1T_EEEEEEEES1T_EEEEEENS3_IKS1T_EENS6_6detail13fail_functionIS25_KS2M_NS8_IS2J_EEEEEEbRKT_RKT0_RT1_N4mpl_5bool_ILb0EEE:字符串表溢出偏移量10002537 /tmp/ccMd36nu.s:汇编程序消息: /tmp/ccMd36nu.s:致命错误:无法关闭调试/osl_lsdyna_k_parser.o:文件太大

似乎缺少优化选项是问题所在。添加 -O1 或 -O2

/usr/bin/x86_64-w64-mingw32-g++ -c -fpermissive -fexceptions -Wall -Wextra -Wno-long-long -Wno-unknown-pragmas -mthreads -Wall -frtti -O1 -g -o 文件.o 文件.cpp

为我解决了问题,甚至允许调试选项 (-g)!

【讨论】:

  • 我遇到了同样的问题,添加这些标志解决了它。感谢分享。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-10
  • 2013-02-02
  • 1970-01-01
相关资源
最近更新 更多