This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] 编译器/MSP430FR5989:为什么将 malloc 和相关函数拉到我的编译中?

Guru**** 2348500 points
Other Parts Discussed in Thread: MSP430FR5989
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/tools/code-composer-studio-group/ccs/f/code-composer-studio-forum/785744/compiler-msp430fr5989-why-is-malloc-and-associated-functions-being-pulled-into-my-build

器件型号:MSP430FR5989

工具/软件:TI C/C++编译器

我正在尝试使用 MSP430fr5989来减少项目上的一些内存使用量。 该项目目前是 c 和 c++的组合。 通过查看.map 文件、可以看到 rts430x_lc_ld_eabi_se.lib 库的 memory.c 文件中使用的许多函数。 有几个人抓住了我的眼睛、我根本不知道为什么他们被包括在内(见下文)。 特别是、包含了 malloc、它会引入 aligned_alloc。 alloced_alloc 是.text 段中最大的函数之一。 我希望能够摆脱这种情况、因为我不是有意进行任何动态内存分配。

有人能帮我弄清楚如何删除这些函数中的某些函数、或者至少知道为什么调用这些函数?

.text 0 00004400 000056d6
(笑声)
00005030 00000198 rts430x_lc_ld_eabi_se.lib:memory.c.obj (.text:aligned_alloc)
(笑声)
000054a2 0000013c rts430x_lc_ld_eabi_se.lib:memory.c.obj (.text:free)
(笑声)
00006516 000000ba rts430x_lc_ld_eabi_se.lib:memory.c.obj (.text:splits)
000065d0 000000b8:fs_mpy.asm.obj (.text)
(笑声)
00008182 00000046 rts430x_lc_ld_eabi_se.lib:memory.c.obj (.text:free_list_insert)
000081c8 00000046:fs_tou.asm.obj (.text)
(笑声)
00008d30 0000002a rts430x_lc_ld_eabi_se.lib:memory.c.obj (.text:free_list_remove)
(笑声)
00009922 0000000c rts430x_lc_ld_eabi_se.lib:memory.c.obj (.text:malloc)

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 USER="Dustin Lane">有人能不能帮助我弄清楚如何删除这些函数中的某些函数、或者至少知道调用它们的原因吗? CCS "Stack Usage"视图和 call_graph 实用程序会显示程序的调用图、作为确定程序栈使用情况的一部分。

    一个副作用是调用图应该显示调用 malloc 和相关函数的内容。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    谢谢切斯特、
    我能够在 CCS 中查看"Stack Usage"视图、但是它不显示任何 malloc 的用法。 我怀疑它在运行时支持库中的某个位置使用、因此最终在.out 文件上使用了 dis430工具。 我最终发现、RTS 库中的"dtor _list.c"文件正在使用 malloc 和 free。
    这是否意味着任何对 C++对象的使用都要求在构建中包含 malloc? 这对我来说似乎仍然是不必要的、并且确实会影响小型存储器 MCU 上 C++的使用。
    作为参考、我使用的是编译器版本 ti-cgt-msp430_18.12.1.LTS

    此外、我找不到 MSP430的 call_graph 实用程序、至少不在编译器的 bin 目录中、这是我唯一知道要查看的位置。 您是否知道它是否存在、如果存在、我在哪里可以找到它?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 user="Dustin Lane">此外、我找不到 MSP430的 call_graph 实用程序、至少不在编译器的 bin 目录中、这是我唯一知道要查看的位置。 您是否知道它是否存在、如果存在、我可能会在哪里找到它?[/quotate]call_graph 是 CG_xml 脚本的一部分- http://software-dl.ti.com/ccs/non-esd/releases/other/applications_packages/cg_xml/index.htm 

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 user="Dustin Lane"]我最终发现 RTS 库中的"dtor_list.c"文件正在使用 malloc 和 free。我尚未进行调查,但您的 C++对象是否包含静态(全局)析构函数?

    从快速看、dtor _list.c 使用 malloc 创建析构函数列表来调用 atexit。  从 MSP430上的 RT-library 中删除 atexit 代码 是一个旧线程、其中指出、如果无法阻止对 每个具有析构函 数的全局对象的 atexit 相关析构函数注册例程的调用、则可以通过向项目中添加一个不执行任何操作的替换函数来最大限度地减少添加的代码。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    谢谢切斯特。
    我能够使用 call_graph 通过"dmain_list.c"文件中的一种方法来确认 malloc 的用法、该方法恰好也是具有最深调用栈的函数。 具体而言,该方法是:"__add_s销毁_to_list()"。

    您是否对解决此问题的任何可能方法有任何见解? 或者、在使用 MSP430的 C++编译器和运行时库时、使用 malloc 是否是不可避免的成本?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    啊、抱歉、我刚才没收到您的回复。

    许多我的 C++对象被创建为单个对象、其中使用静态关键字声明该对象、例如:

    ModeShutdown* ModeShutdown::getInstance()

    静态模式关闭实例;
    返回实例(&I);


    对于我的所有对象、我使用默认析构函数。 我假设这意味着这些对象随后具有静态/全局析构函数、您是否同意?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我发现这个其他的旧线程似乎解决了同样的问题:
    e2e.ti.com/.../1129174

    最终导致对编译器的增强请求、即使已经超过5年了、该请求仍处于开放状态。 您是否可以更深入地了解此增强请求的状态:SDSCM00049923?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 user="Dustin Lane">我假设这意味着这些对象随后具有静态/全局析构函数、您是否同意?是的、我同意。

    [引用 user="Dustin Lane">您是否能更好地了解此增强请求的状态:SDSCM00049923?否

    考虑到嵌入式程序通常不会退出、因此 不需要运行静态/全局析构函 数、如前一个线程中建议的变通方法是向项目中添加一个 stub __cxa_atexit 函数。

    使用 TI MSP430编译器 v18.12.1.LTS 将以下内容添加到主 CPP 源文件中、消除了对具有静态/全局析构函数但未使用动态存储器的测试程序中 malloc 的调用:

    typedef void * a_DSO_handle;
    typedef void (* a_cxa_dtor_ptr)(void *);
    
    extern "C" int _ cxa_atexit (a_cxa_dtor_ptr dify_routine、
    无效 *对象,
    A_DSO_Handle DSO_Handle)
    {
    返回0;
    } 

    由于它替换了运行时库中的一个私有函数、因此它可能会在编译器更新之后中断。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    谢谢切斯特。
    我尝试使用该代码段进行编译、但最终得到了__cxa_atexit()的符号重新定义错误,该错误声明它首先在 main.cpp 中定义,然后在 RTS 文件 dtor _list.c 中重新定义

    我不确定如何解决这一重新定义问题、但不幸的是、不管怎样、这似乎不是一个可靠的解决方案。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 USER="Dustin Lane)]我不确定如何解决这一重新定义问题,但不幸的是,不管怎样,这似乎不是一个可靠的解决方案。由于 dtor_list.c 具有多个 atexit 函数,可以定义以下代码的桩模块,这可能有助于消除代码的错误:

    typedef void * a_DSO_handle;
    typedef void (* a_cxa_dtor_ptr)(void *);
    
    extern "C" int _ cxa_atexit (a_cxa_dtor_ptr dify_routine、
    无效 *对象,
    A_DSO_Handle DSO_Handle)
    {
    返回0;
    }
    
    extern "C" int __cxa_ia64_exit (a_cxa_dtor_ptr s销毁 例程、
    无效 *对象,
    A_DSO_Handle DSO_Handle)
    {
    返回0;
    }
    
    extern "C" int atexit (void (* function)(void)
    ){
    返回0;
    } 

    我同意、必须存根运行时库函数并不是一个可靠的解决方案。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    遗憾 的是,在这件事中提出的第一个改进请求,ID 为 SDSCM00049923,从未得到执行。  因此、我提交了类似的条目 CodeGen-6090。  欢迎您在我的签名中使用下面的 SDOWP 链接进行访问。

    关于变通办法,我同意切斯特·吉隆的这一发言。

    [引用 user="Chester Gillon"]我同意必须将运行时库函数存根不是一个可靠的解决方案。

    不幸的是、这是我找到的最佳解决方法。

    谢谢、此致、

    乔治

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    谢谢、George。 我希望这会在不久的将来将其转换为编译器更新。 现在、我只需要与它一起生活。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    对于具有静态作用域(全局)对象和非普通析构函数的 C++程序而言、对 malloc 的需求几乎只是一个事实。 C++标准要求我们支持任意数量的此类对象、这意味着销毁列表的动态分配。 从理论上讲、如果链接器能够确定程序永远不会退出、它可能会省略 exit/aexit 等、但链接器没有我们需要的基础结构。  在任何情况下、如果链接器能够确定程序从不退出、则会执行的操作是将__cxa_atexit 存根,因此它看起来与您自己将它们存根时没有太大的区别。
    总之:我们不会马上解决这个问题。  如果要避免仅为 C++析构函数在 malloc 中拖动、请将__cxa_exit 存根。