据说用-O3
gcc 优化选项编译 GNU 工具和 Linux 内核会产生奇怪和时髦的错误。这是真的吗?有没有人尝试过,还是只是一个骗局?
从这篇文章可以看出这FS:[0x28]
是一个堆栈金丝雀。我在这个函数上使用 GCC 生成相同的代码,
void foo () {
char a[500] = {};
printf("%s", a);
}
Run Code Online (Sandbox Code Playgroud)
具体来说,我得到这个程序集..
0x000006b5 64488b042528. mov rax, qword fs:[0x28] ; [0x28:8]=0x1978 ; '(' ; "x\x19"
0x000006be 488945f8 mov qword [local_8h], rax
...stuff...
0x00000700 488b45f8 mov rax, qword [local_8h]
0x00000704 644833042528. xor rax, qword fs:[0x28]
0x0000070d 7405 je 0x714
0x0000070f e85cfeffff call sym.imp.__stack_chk_fail ; void __stack_chk_fail(void)
; CODE XREF from 0x0000070d (sym.foo)
0x00000714 c9 leave
0x00000715 c3 ret
Run Code Online (Sandbox Code Playgroud)
什么是设置值fs:[0x28]
?内核,还是 GCC 投入了代码?你能在内核中显示代码,或者编译成设置的二进制文件fs:[0x28]
吗?金丝雀是在启动时重新生成的,还是在进程生成时重新生成的?这是在哪里记录的?
我最近安装了 XUbuntu 11.10 64 位,但在编译最简单的 pthread 示例时遇到问题。
这是代码pthread_simple.c
:
#include <stdio.h>
#include <pthread.h>
main() {
pthread_t f2_thread, f1_thread;
void *f2(), *f1();
int i1,i2;
i1 = 1;
i2 = 2;
pthread_create(&f1_thread,NULL,f1,&i1);
pthread_create(&f2_thread,NULL,f2,&i2);
pthread_join(f1_thread,NULL);
pthread_join(f2_thread,NULL);
}
void *f1(int *x){
int i;
i = *x;
sleep(1);
printf("f1: %d",i);
pthread_exit(0);
}
void *f2(int *x){
int i;
i = *x;
sleep(1);
printf("f2: %d",i);
pthread_exit(0);
}
Run Code Online (Sandbox Code Playgroud)
这是编译命令
gcc -lpthread pthread_simple.c
结果:
lptang@tlp-linux:~/test/test-pthread$ gcc -lpthread pthread_simple.c /tmp/ccmV0LdM.o:在函数“main”中: pthread_simple.c:(.text+0x2c):对`pthread_create'的未定义引用 pthread_simple.c:(.text+0x46):对`pthread_create'的未定义引用 pthread_simple.c:(.text+0x57):对`pthread_join'的未定义引用 pthread_simple.c:(.text+0x68):对`pthread_join'的未定义引用 collect2: ld 返回 1 个退出状态 …
我sudo apt-get install
在 Ubuntu 上安装了 boost 。后来我不必为 gcc 提供I
标志以及使用 boost 的 boost 库的路径!我也没有做任何事情pkg-config --cflags --libs
。这里有什么奥秘?gcc 如何知道 boost 在哪里以及它如何自动链接到它?
我想知道为什么当我gcc -v
在 Arch Linux 下运行时,它unknown
在这些输出中显示这个词:
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-unknown-linux-gnu/5.1.0/lto-wrapper
Target: x86_64-unknown-linux-gnu
Run Code Online (Sandbox Code Playgroud)
而在其他发行版中,例如 ubuntu,它显示发行版名称,例如ubuntu
:
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-ubuntu-linux-gnu/5.1.0/lto-wrapper
Target: x86_64-ubuntu-linux-gnu
Run Code Online (Sandbox Code Playgroud) 我正在尝试更多地了解 Linux 中的库版本控制以及如何将其全部投入使用。这是上下文:
-- 我有两个版本的动态库,它们公开了相同的接口集,比如libsome1.so
和libsome2.so
。
- 应用程序链接到libsome1.so
.
-- 此应用程序用于libdl.so
动态加载另一个模块,例如libmagic.so
.
——现在libmagic.so
是联防libsome2.so
。很显然,在不使用连接器脚本隐藏符号libmagic.so
,在运行时在接口的所有调用libsome2.so
决心libsome1.so
。这可以通过检查 返回libVersion()
的值与宏的值来确认LIB_VERSION
。
-- 所以我接下来尝试编译和链接libmagic.so
一个链接器脚本,该链接器脚本隐藏了除 3 之外的所有符号,这些符号在其中定义libmagic.so
并由它导出。这有效......或者至少libVersion()
和LIB_VERSION
值匹配(并且它报告版本2而不是1)。
-- 但是,当一些数据结构被序列化到磁盘时,我注意到一些损坏。在应用程序的目录中,如果我删除libsome1.so
并在其指向的位置创建一个软链接libsome2.so
,一切都按预期工作,并且不会发生相同的损坏。
我不禁想到这可能是由于运行时链接器对符号的解析存在一些冲突造成的。我已经尝试了很多东西,比如尝试链接libsome2.so
以便所有符号都被别名化symbol@@VER_2
(我仍然对此感到困惑,因为该命令nm -CD libsome2.so
仍然将符号列为symbol
和不列出symbol@@VER_2
)......似乎没有任何效果!!!帮助!!!!!!
我似乎缺少一些手册页,特别是 gcc 和 g++。我指定该部分无济于事。whereis
没有列出这两个的手册页,所以我认为它们根本不存在。
使用谷歌我得到了很多,例如:http : //linux.die.net/man/1/g++(虽然似乎是普通的 HTML...还是手册页标记?)
我认为这将是学习如何手动替换它们的好机会。我想我正在寻找 gcc.1.gz 文件?
我是从 GNU 或 Debian 获得它,还是可以以某种方式自动化?在这些文件中投入了多少工作——如果我得到一个,它可能是 99% 正确的还是它们真的随着时间/架构的不同而有很大不同?
我有一个带有 gcc 版本 4.4.7 的 RHEL 6 服务器。我想更新 gcc 版本(我认为当前的版本是 4.8)。百胜更新不起作用。此外,对 CentOS上类似问题的 SO 答案不起作用。我按照接受的答案中的方法进行操作,输出是“获取用于 testing-1.1-devtools-6 的存储库数据时出错,未找到存储库”。另外我不确定我是否应该遵循 CentOs 的方法。
有人在 RHEL 6 x86_64 服务器中更新了 gcc 吗?
我经常从源代码构建各种库以供使用,例如 gmp-6.1.2、mpfr-4.0.1 和 gcc-7.x。这样做时,我更喜欢使用,--prefix=/usr/local/gcc-7.2.0
所以我确切地知道它的安装位置并且不会弄乱现有的库。然后我基本上只知道最后make install
告诉我的是更新或设置LD_LIBRARY_PATH
,有时但不总是LD_RUN_PATH
。
大多数情况下,我只是LD_LIBRARY_PATH
稍后根据需要手动设置,或者以类似的方式全局设置它/etc/bash.bashrc.local
并且有效。
这make install
就是说:
Libraries have been installed in:
/usr/local/mfprtest/lib
If you ever happen to want to link against installed libraries
in a given directory, LIBDIR, you must either use libtool, and
specify the full pathname of the library, or use the '-LLIBDIR'
flag during linking and do at least one of the following:
- add LIBDIR to the 'LD_LIBRARY_PATH' environment variable …
Run Code Online (Sandbox Code Playgroud) 我最近安装Ubuntu 18.04, Linux foobar-VirtualBox 4.15.0-23-generic #25-Ubuntu SMP Wed May 23 18:02:16 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
在虚拟机上。我想为带有硬浮点的Cortex-M4F CPU 交叉编译应用程序,因此我已经安装了包gcc-arm-none-eabi
版本15:6.3.1+svn253039-1build1
以及 libnewlib-arme-none-eabi
版本2.4.0.20160527-3
.
由于使用硬浮点数的目标文件与使用软浮点数的库之间存在冲突,因此出现链接器错误。一些研究表明这是一个已知的Ubuntu 18.04 (Bionic Beaver) 问题:
请注意,我确实提供了正确的编译器和链接器标志,并且该项目使用来自GNU ARM Embedded的 Windows 交叉工具链正确构建。我认为在这里粘贴完整的错误是没有意义的。如果有人认为这是必需的,我很乐意编辑这个问题。
根据我的基本理解,我有两种解决方案来获得功能性 GCC ARM 工具链:
gcc-arm-none-eabi
以返回到工作版本gcc-arm-none-eabi
并安装(gcc-arm-embedded
从 PPA安装 gcc-arm-embedded)为了降级,gcc-arm-none-eabi
我必须在我的包管理器中找到以前的版本。我首先用 更新了包列表sudo apt …