似乎glibc 2.14引入了新版本memcpy(修复bug 12518).然后,针对glibc 2.14+编译的程序将包含动态链接memcpy@GLIBC_2.14,这在旧版本的glibc中显然不可用.
但是,glibc 2.14+显然仍然包含旧memcpy@GLIBC_2.2.5符号以实现向后兼容.我希望能够以这样的方式编译一些程序,使它们与旧的glibc版本二进制兼容.如何在具有glibc 2.14+的系统上编译程序,以便它使用这个旧的符号版本?如果该过程必然是特定于编译器的,那么我正在使用GCC(但是知道如何在其他编译器上执行它也会很好).
(在一个侧面说明,我必须承认不知道一大堆有关版本的符号,比如如何产生,以及如何使用它们,或者他们是否是ELF特定的或应被认为是现代的ABI标准的一部分;我还没有找到任何关于它的文件.关于这个问题,有没有很好的信息来源?)
对于x86_64-linux,glibc的libm(以及标题?)是否有更快的替代品?
我正在尝试在 ubuntu (18.04) 主机上运行一些 haskell 代码,该代码是在我的笔记本电脑上编译的。
host: 4.15.0-36-generic #39-Ubuntu SMP Mon Sep 24 16:19:09 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
laptop: 4.14.74-1-MANJARO #1 SMP PREEMPT Fri Oct 5 14:16:52 UTC 2018 x86_64 GNU/Linux
Run Code Online (Sandbox Code Playgroud)
我得到的错误是
/lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.28' not found
Run Code Online (Sandbox Code Playgroud)
经过一些研究,我了解到这是因为我的笔记本电脑安装了 glibc 2.28 版本,但主机只有 libc6 2.27。
我做了一些谷歌搜索,认为也许 docker 可以解决这个问题。但是,我刚刚使用以下 Dockerfile 创建了一个 docker 映像,但它不起作用(相同的 GLIBC_2.28 错误)
FROM fpco/stack-build:lts-12.9 as builder
RUN mkdir /opt/build
COPY . /opt/build
RUN cd /opt/build && stack build
FROM ubuntu:18.04
RUN mkdir -p /opt/myapp
WORKDIR /opt/myapp
RUN apt-get …Run Code Online (Sandbox Code Playgroud) 假设我有以下本地 gcc, g++ 版本:
$ gcc -v
$ g++ -v
gcc version 6.3.1
Run Code Online (Sandbox Code Playgroud)
与我的编译器版本相比,我不理解以下内容的关系和含义:
这是指什么?
/usr/lib64/libstdc++.so.6
Run Code Online (Sandbox Code Playgroud)
尝试运行二进制文件时出现此错误,这是GLIBCXX_3.4.20指什么?为什么数字以3开头?
/lib64/libstdc++.so.6: version `GLIBCXX_3.4.20' not found
Run Code Online (Sandbox Code Playgroud)
这是什么?
$ strings /usr/lib64/libstdc++.so.6 | grep GLIBCXX
GLIBCXX_3.4
GLIBCXX_3.4.1
GLIBCXX_3.4.2
GLIBCXX_3.4.3
GLIBCXX_3.4.4
GLIBCXX_3.4.5
GLIBCXX_3.4.6
GLIBCXX_3.4.7
GLIBCXX_3.4.8
GLIBCXX_3.4.9
GLIBCXX_3.4.10
GLIBCXX_3.4.11
GLIBCXX_3.4.12
GLIBCXX_3.4.13
GLIBCXX_3.4.14
GLIBCXX_3.4.15
GLIBCXX_3.4.16
GLIBCXX_3.4.17
GLIBCXX_3.4.18
GLIBCXX_3.4.19
Run Code Online (Sandbox Code Playgroud)
ldd版本怎么样?
ldd --version
ldd (GNU libc) 2.17
Run Code Online (Sandbox Code Playgroud)
我无法将所有这些版本号链接在一起。
我正在尝试执行以下操作:
\n\n将简单 test.c 的 libc 从系统默认值(Debian 9.11、libc-2.24.so)更改为 libc 2.27。
\n\n这是我的尝试:
\n\nuser@pc:~/patchelf_test$ cat test.c \n#include <stdio.h>\n\nint main(int argc, char **argv)\n{\n printf("hello patchelf\\n");\n\n return 0;\n}\nuser@pc:~/patchelf_test$ gcc test.c -o test\nuser@pc:~/patchelf_test$ ./test\nhello patchelf\nuser@pc:~/patchelf_test$ ldd test\n linux-vdso.so.1 (0x00007ffd9d1d8000)\n libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f7ea0290000)\n /lib64/ld-linux-x86-64.so.2 (0x00007f7ea0831000)\nuser@pc:~/patchelf_test$ patchelf --set-interpreter ./libc6-amd64_2.27-3ubuntu1_i386.so test\nwarning: working around a Linux kernel bug by creating a hole of 2093056 bytes in \xe2\x80\x98test\xe2\x80\x99\nuser@pc:~/patchelf_test$ ldd test\n linux-vdso.so.1 (0x00007fff20b9a000)\n libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fa46a35e000)\n ./libc6-amd64_2.27-3ubuntu1_i386.so => /lib64/ld-linux-x86-64.so.2 (0x00007fa46a900000)\nuser@pc:~/patchelf_test$ ./test\nGNU C Library (Ubuntu GLIBC 2.27-3ubuntu1) stable …Run Code Online (Sandbox Code Playgroud) aarch64我正在我的系统上交叉编译应用程序x86 Ubuntu Bionic,但遇到glibc版本不匹配的问题。我的交叉编译工具链使用 v2.27,而运行应用程序的系统使用 v2.24。我认为可能是因为我的工具链版本太高,所以我决定降级。
删除所有以前的交叉编译安装后,我安装了gcc-4.8-aarch64-linux-gnu(因为我已经在不同的主机系统上成功地使用此版本交叉编译了应用程序),认为它会安装旧版本aarch64的glibcto /usr/aarch64-linux-gnu/lib/。然而,再次安装了v2.27(我在安装新的交叉编译工具链之前验证了该目录不存在)。
所以我的问题是双重的:
aarch64版本?它与我自己的系统版本直接相关吗?glibcgcc-4.8-aarch64-linux-gnux86glibcaarch64版本glibc)版本的正确方法?我正在尝试使用 VS Code 的通过 ssh 功能进行远程开发。连接到远程服务器时我遇到:
Missing GLIBCXX >= 3.4.18!
>Found versions 3.4.1
> 3.4.2
> ...
> 3.4.13
Missing GLIBC >= 2.17!
Found version ldd (GNU libc) 2.12
Run Code Online (Sandbox Code Playgroud)
在遥控器上,我加载模块gcc/7.3.0并确认版本:
gcc --version
> gcc (GCC) 7.3.0
Run Code Online (Sandbox Code Playgroud)
并且还发现:
ldd --version
> ldd (GNU libc) 2.12
Run Code Online (Sandbox Code Playgroud)
在/lib我找到libc-2.12.so并发现GLIBC的最大版本是2.12:
strings libc-2.12.so | grep GLIB
> GLIBC_2.0
> GLIBC_2.1
> ...
> GLIBC_2.12
Run Code Online (Sandbox Code Playgroud)
但是,我可以在系统的另一个位置找到所需版本的库/usr/lots/of/directories/gcc/x86_64-pc-linux-gnu/7.3.0:
strings libstdc++.so.6.0.24 | grep GLIB
> GLIBCXX_3.4
> ...
> GLIBCXX_3.4.24
> ... …Run Code Online (Sandbox Code Playgroud) C 规范要求所有 C 程序都有 3 个开放的流可供它们使用:stdout, stdin, stderr.
用户可以根据需要使用这些流,例如:
fprintf(stdout, "lol");
fputs("oops", stderr);
fgets(buffer, 20, stdin);
Run Code Online (Sandbox Code Playgroud)
C 标准库中的一些函数隐式使用这些,例如:
printf("lol"); /* implicitly uses stdout */
puts("rofl"); /* implicitly uses stdout */
int c = getchar(buffer); /* implicitly uses stdin */
Run Code Online (Sandbox Code Playgroud)
stderr?stderr?我最近发现,我可以相对容易地从 .NET 进行 Linux 系统调用。
例如,要查看我是否需要,sudo我只需签名如下:
internal class Syscall {
[DllImport("libc", SetLastError = true)]
internal static extern uint geteuid();
// ...
}
Run Code Online (Sandbox Code Playgroud)
public static bool IsRoot => Syscall.geteuid() == 0;
Run Code Online (Sandbox Code Playgroud)
整洁的。比其他一切都更容易和更快,对吗?这是最简单的系统调用,其他使用字符串和结构。
经过一番深入研究文档并自行测试后,我发现默认编组器libc可以将字符串 from 直接映射到stringfrom char*,大多数其他内容只需要使用一些手动映射IntPtr到结构的乐趣。
所以以类似的方式我快速绘制chmod了chown,,,,,,,, 。所有这些都在我的 Ubuntu VM 上进行了测试,有效。lchowngetgrnamgetpwnamgetuidsymlink
我什至制作了自己的超简洁Chmod实现,其工作方式与chmod接受相对权限(如u+wX. 并遍历文件系统。
这就是我失去一个晚上的地方。我需要原始权限,我读到可以通过调用获得它们stat。可能会出现什么问题?
首先,我使用手动文档
制作了Stat结构: https://man7.org/linux/man-pages/man2/stat.2.htmlLinux
然后我做了相应的extern。
第一个惊喜:找不到入口点。
我挖啊挖啊,又挖了一些。直到我打开 …
我们正在构建一个针对 Ubuntu 18.04 LTS 和所有更高版本的 GTK3 应用程序。但是,当我们在 Ubuntu 20.04 版本中构建应用程序时,该应用程序无法在较旧的 Ubuntu 版本上运行。它说
libc.so.6:找不到版本“GLIBC_2.31”(.source 需要)
但如果我在 Ubuntu 18.04 上构建一个应用程序,它将适用于所有后续的 Ubuntu 版本。Ubuntu 18.04 默认情况下有 GLIBC 版本 2.27,该版本适用于所有后续版本。
那么有什么方法可以告诉我的应用程序,该应用程序是使用 GLIBC 2.27 构建的,无论构建该应用程序的操作系统是什么版本?有什么方法可以在构建过程中将 GLIBC 版本的信息提供给应用程序吗?