eCos编译Synthethic Target程序时无法解析__sprintf_chk的解决办法
mingdu.zheng <at> gmail <dot> com
http://blog.csdn.net/zoomdy/article/details/10615853
官方已解决此问题:
详见:http://hg-pub.ecoscentric.com/ecos/rev/a1df75458e13
问题描述:
在Xubuntu 12.04下编译eCos Synthetic Target的测试程序(通过eCos图形配置工具菜单Build >> Tests),当编译cxxsupp测试程序时出现未解析符号“__sprintf_chk”。
错误输出:
gcc -L/home/pangu/ecos/conf/synth_default_install/lib -Ttarget.ld -o /home/pangu/ecos/conf/synth_default_install/tests/infra/current/tests/cxxsupp tests/cxxsupp.o -g -nostdlib -Wl,-static -Wl,--fatal-warnings
make[1]:正在离开目录 `/home/pangu/ecos/conf/synth_default_build/infra/current'
/usr/lib/gcc/i686-linux-gnu/4.6/libsupc++.a(cp-demangle.o): In function `.L741':
make:离开目录“/home/pangu/ecos/conf/synth_default_build”
(.text+0x4088): undefined reference to `__sprintf_chk'
/usr/lib/gcc/i686-linux-gnu/4.6/libsupc++.a(cp-demangle.o): In function `.L747':
(.text+0x45c3): undefined reference to `__sprintf_chk'
/usr/lib/gcc/i686-linux-gnu/4.6/libsupc++.a(cp-demangle.o): In function `.L747':
(.text+0x473b): undefined reference to `__sprintf_chk'
/usr/lib/gcc/i686-linux-gnu/4.6/libsupc++.a(cp-demangle.o): In function `.L747':
(.text+0x4833): undefined reference to `__sprintf_chk'
/usr/lib/gcc/i686-linux-gnu/4.6/libsupc++.a(cp-demangle.o): In function `d_print_mod_list':
(.text+0x62e9): undefined reference to `__sprintf_chk'
collect2: ld 返回 1
make[1]: *** [/home/pangu/ecos/conf/synth_default_install/tests/infra/current/tests/cxxsupp] 错误 1
make: *** [tests] 错误 2
解决办法:
在packages\hal\synth\arch\<version>\src\synth_entry.c文件中追加以下代码。
#include <stdarg.h>
#include <limits.h>
#include <stdio.h>// __chk_fail -- terminate a function in case of buffer overflow
// copy from gcc-4.8.1/libssp/ssp.c
void __chk_fail (void)
{CYG_FAIL("Buffer overflow detected, aborting");diag_printf("Application error: buffer overflow detected.\n");cyg_hal_sys_exit(1);for(;;);
}// __sprintf_chk -- convert formatted output, with stack checking
// copy from gcc-4.8.1/libssp/sprintf-chk.c
int __sprintf_chk (char *s, int flags __attribute__((unused)),size_t slen, const char *format, ...)
{va_list arg;int done;va_start (arg, format);if (slen > (size_t) INT_MAX)done = vsprintf (s, format, arg);else{done = vsnprintf (s, slen, format, arg);if (done >= 0 && (size_t) done >= slen)__chk_fail ();}va_end (arg);return done;
}
问题原因:
1、Xubuntu 12.04,以及其它最近发行的Linux版本默认开启了GCC的堆栈保护特性,因此sprintf函数调用将会被替换为__sprintf_chk函数调用,__sprintf_chk除了实现sprintf的功能外还将检查堆栈是否溢出。
2、new操作符的实现是由编译器提供的(libsupc++.a),编译eCos Synthetic Target时使用的是Linux下的本地编译器,因此libsupc++.a是在打开堆栈保护特性的情况下编译的,也就是说如果new操作符引用或者间接引用了sprintf函数,那么实际引用的将是__sprintf_chk。
3、new操作符在分配内存失败时需要抛出异常,异常机制经过一系列的函数调用,最终会调用cp-demangle.o文件内的__cxa_demangle函数逆向解析C++名称包装,例如将_Znwj解析为operator new(unsigned int),__cxa_demangle引用了sprintf进行字符串格式化,而在开启GCC堆栈保护特性的情况下,sprintf自动被替换为__sprintf_chk,在Xubuntu中,__sprintf_chk函数由glibc提供,而eCos Synthetic Target虽然编译成Linux下的一个进程,但是使用的仍然是eCos自带的C库,而不是Linux中的C库,而eCos中的C库并没有实现__sprintf_chk函数,因此在链接过程中产生无法解析的符号“__sprintf_chk”,解决办法是实现该函数。
深入解析:
编译器将new和delete操作符的相关代码打包到libsupc++.a静态库(new_op.o和del_op.o),因此使用了new和delete操作符的程序将引用该静态库内的相关代码,根据C++标准要求,new操作符在内存分配失败是将抛出异常,从底层实现角度就是将会调用__cxa_throw函数,而__cxa_throw函数引用了__cxxabiv1::__terminate_handler,这是一个函数指针,该函数指针指向__gnu_cxx::__verbose_terminate_handler函数,该函数引用了cp-demangle.o文件内的__cxa_demangle函数,__cxa_demangle函数引用了__sprintf_chk,使用nm工具输出.o文件符号可以非常清楚地看到函数间可能的调用关系,下面是nm工具的输出,已删除无关的符号,T字母标识的是该.o文件定义的符号,U字母标识的是该.o文件引用的符号。
new_op.o:
00000000 T _Znwj(operator new(unsigned int))U __cxa_throweh_throw.o:U _ZN10__cxxabiv119__terminate_handlerE(__cxxabiv1::__terminate_handler)
00000000 T __cxa_throweh_term_handler.o:
00000000 D _ZN10__cxxabiv119__terminate_handlerEU _ZN9__gnu_cxx27__verbose_terminate_handlerEv(__gnu_cxx::__verbose_terminate_handler())vterminate.o:
00000000 T _ZN9__gnu_cxx27__verbose_terminate_handlerEvU __cxa_demanglecp-demangle.o:
00006e20 T __cxa_demangleU __sprintf_chk
具体的实现以及调用层次关系可以阅读libsupc++的源代码,位于gcc源代码的libstdc++-v3\libsupc++目录下。
补充说明:
cxxsupp是eCos用来测试C++支持的测试程序,其中使用了new和delete操作符,如果这个测试通不过意味着在应用中不能够使用new和delete操作符。默认情况下new和delete操作符的实现代码由编译器提供,即使是eCos也是如此,除非进行显式地重定义覆盖编译器的默认实现。
除了libsupc++.a之外,根据需要还将链接libgcc.a、libgcc_eh.a,这两个静态包同样是由编译器提供的。
eCos编译Synthethic Target程序时无法解析__sprintf_chk的解决办法相关推荐
- VC++ MFC单文档应用程序SDI下调用glGenBuffersARB(1, pbo)方法编译通过但执行时出错原因分析及解决办法:glewInit()初始化的错误...
1.问题症状 在VC++环境下,利用MFC单文档应用程序SDI下开发OpenGL程序,当调用glGenBuffersARB(1, &pbo)方法编译通过但执行时出错,出错代码如下: OpenG ...
- QtCreator 编译时提示 warning C4819 的解决办法
QtCreator 编译时提示 warning C4819 的解决办法 用 QtCreator 和Visual C++ 编译器编译程序时经常会出现类似的警告: warning C4819: 该文件包含 ...
- 台达DOP系列触摸屏上传程序时提示“中止传输数据”怎样解决?
台达DOP系列触摸屏上传程序时提示"中止传输数据"怎样解决? 如下图所示,在上传HMI程序时,首先会提示我们输入密码, 输入正确的密码后,正常情况下,就可以进行程序画面的上传了. ...
- Win7 IIS7.5运行ASP时出现500错误的解决办法
http 500内部服务器错误说明IIS服务器无法解析ASP代码,下面为大家介绍下Win7 IIS7.5运行ASP时出现500错误的解决办法 http 500内部服务器错误说明IIS服务器无法解析AS ...
- 使用 QT 时遇到的问题及解决办法
使用 QT 时遇到的问题及解决办法 Use multi-arg instead [clazy-qstring-arg] 不要使用一连串的 arg().arg().arg() QString(" ...
- mysql update语句卡死_oracle执行update语句时卡住问题分析及解决办法
问题 开发的时候debug到一条update的sql语句时程序就不动了,然后我就在plsql上试了一下,发现plsql一直在显示正在执行,等了好久也不出结果.但是奇怪的是执行其他的select语句却是 ...
- keil MDK cannot access target,shutting down debug session的解决办法
Erase Full Chip:烧写程序之前擦除整个Flash存储器. Erase Sectors: 烧写程序之前擦除程序要使用的扇区. Do not Erase: 不进行擦除操作 cannot ac ...
- 手机安装软件解析包错误解决办法
下载了一款新的APP,满心欢喜的正准备体验的时候,却发现出现了"解析包时出现问题"之类的提示,连安装都无法成功,这样的体验肯定非常不妙.那么安卓解析包出现问题时有没有好的解决办法呢 ...
- nginx alias php,Nginx Alias 无法解析PHP的解决办法
Nginx Alias 无法解析PHP的解决办法: server { listen 80; server_name xxxx.com.cn; error_log /tmp/eror.l ...
最新文章
- 身份证号码验证-支持新的带x身份证
- python logsumexp示例
- netfilter与iptables表规则建立
- 避免在ConcurrentHashMap.computeIfAbsent()中进行递归
- java 中的流_Java中的流(IO
- 全排列及相关扩展算法(七)——组合数的字典序(另含全章代码整理)
- mysql innodb 间隙锁_Mysql innodb 间隙锁
- 解决sklearn库使用过程中No module named model_selection的错误
- .ps是什么格式_用Word修图,真的比PS简单十倍不止!可惜知道的人太少了......
- 《论语》全译——孔子生平
- win10系统截图快捷键
- matlab中contourf函数怎么用_有人可以解释如何使用contourf在MATLAB中绘制这个总和吗?...
- Mac使用Homebrew极速安装启动RabbitMQ一把梭
- Ubuntu系统迁移至固态硬盘(生产环境勿用)
- mysql使用group by查询报错SELECT list is not in GROUP BY clause and contains nonaggregated column.
- xpath.extract() 的使用
- Java代理模式(Cglib)代理模式
- 2022视力矫正展,2022青少年眼睛健康展会,护眼产品展
- 神奇的sqrt函数以及高精度记时函数
- 作为打工人,普通人努力的意义何在?
热门文章
- 蓝桥杯单片机备战(四)共阳数码管的静态显示
- Acrobat 删除pdf页面
- openstack 网络更改版
- 安卓 11 文件储存
- “搬砖”机器人两天盖一栋房?泥瓦匠表示很心累
- Expeditious Cubing(浮点数处理)
- php7 error reporting,php中的error_reporting(7)的含义
- 浅谈 Web 3.0
- PP实施经验分享(17)——S4 PP与ME标准接口报工函数“CO_MES_PRODORDCONF_CREATE_TT”
- 玩转docker之mysql容器(常见问题汇总-续更)