标签: elf

如何减少默认的C++内存消耗?

我有一个用C++编写的服务器应用程序.启动后,它在x86 Linux上使用大约480 KB的内存(Ubuntu 8.04,GCC 4.2.4).我认为480 KB是一个过多的内存:服务器甚至没有做任何事情,没有客户端连接到服务器.(另请参阅下面的评论,其中我解释了为什么我认为480 KB是大量内存.)服务器在初始化期间唯一做的事情就是产生一个或两个线程,设置几个套接字,以及其他简单的东西.非常记忆密集.

请注意,我在谈论实际内存使用情况,而不是VM大小.我通过在空闲笔记本电脑上启动我的服务器的100个实例来测量它,并在启动服务器实例之前和之后用"免费"测量系统内存使用情况.我已经考虑了文件系统缓存和类似的东西.

经过一些测试后,看起来C++运行时中的某些东西会导致我的服务器使用这么多内存,即使服务器本身没有做任何事情.例如,如果我插入

getchar(); return 0;
Run Code Online (Sandbox Code Playgroud)

之后

int main(int argc, char *argv[]) {
Run Code Online (Sandbox Code Playgroud)

然后每个实例的内存使用量仍为410 KB!

我的应用程序仅依赖于Curl和Boost.我有很多C编程经验,我知道C库在使用之前不会增加内存消耗.

我发现的其他事情:

  • 一个简单的hello world C app消耗大约50 KB的内存.
  • 一个简单的hello world C app链接到Curl,但不使用Curl,也消耗大约50 KB的内存.
  • 一个简单的hello world C++应用程序(没有Boost)消耗大约100 KB的内存.
  • 一个简单的hello world C++应用程序包含一些Boost标头,但实际上并没有使用Boost,它消耗大约100 KB的内存.使用'nm'检查可执行文件时没有Boost符号.

我的结论如下:

  1. Gcc抛弃了未使用的Boost符号.
  2. 如果我的应用程序使用Boost,那么C++运行时(可能是动态链接器)中的某些内容会导致它使用大量内存.但是什么?我怎样才能知道这些东西是什么,我能对它们做些什么?

我记得几年前关于C++动态链接器问题的一些KDE讨论.之后的Linux C++动态链接器导致KDE C++应用程序启动时间慢,内存消耗大.据我所知,这些问题已在C++运行时修复.但类似的东西可能是我所看到的过度记忆消耗的原因吗?

来自gcc /动态链接专家的答案非常感谢.

对于那些好奇的人,有问题的服务器是Phusion Passenger的日志记录代理:https://github.com/FooBarWidget/passenger/blob/master/ext/common/LoggingAgent/Main.cpp

c++ memory-management elf dynamic-linking low-level

15
推荐指数
2
解决办法
2869
查看次数

如何知道ELF目标文件中的调试信息类型?

我有一个ELF目标文件.我想知道它包含哪种类型的调试信息.它是用PPC架构的Diab编译器(C源代码)编译的.我很确定它是用调试符号构建的.

我试过提取调试信息,dwarfdump但我不工作,所以我猜调试信息不​​是DWARF类型.

$ dwarfdump file.elf
No DWARF information present in file.elf
Run Code Online (Sandbox Code Playgroud)

使用objdump显示调试信息是空的.

$ objdump -g file.elf 
file.elf:     file format elf32-powerpc
Run Code Online (Sandbox Code Playgroud)

可能是这个ELF文件不包含调试信息,即使ELF文件中有调用的部分.debug_sfnames,.debug_srcinfo并且.debug.srcinfo?或者调试信息是以objdump无法处理的格式存储的?

c powerpc elf debug-symbols

15
推荐指数
3
解决办法
1万
查看次数

如何在C(gcc)中获取自定义ELF部分的起始和结束地址?

我已经看到使用gcc __section__属性(特别是在Linux内核中)将数据(通常是函数指针)收集到自定义ELF部分中.如何检索和使用这些自定义部分中的"东西"?

c gcc elf

15
推荐指数
3
解决办法
1万
查看次数

将共享库打包到精灵中

是否有一个实用程序可以将精灵需要的所有 SO变为静态然后将精灵转换成SO的自由?

linux shared-libraries elf

14
推荐指数
1
解决办法
6197
查看次数

Linux上的COFF或Windows上的ELF

是否可以在UNIX上运行COFF可执行文件或在Windows上运行ELF可执行文件?在Windows和UNIX上运行任一文件类型的步骤是什么?我只是好奇.

unix windows coff elf

14
推荐指数
2
解决办法
1万
查看次数

ELF核心文件格式

如果没有挖掘GDB源代码,我在哪里可以找到有关用于创建核心文件的格式的文档?

ELF规范离开核心文件格式打开,所以我想这应该是GDB规范的一部分!遗憾的是,我没有从GNU的gdb文档中找到任何帮助.

这就是我要做的事情:将虚拟地址映射到包含正在运行的进程的可执行文件/库中的函数名称.为此,我首先要从核心文件中找出从虚拟地址空间到可执行文件/库的名称的映射,然后深入到相关文件中以获取符号信息.

现在'readelf -a core'告诉我核心文件中的几乎所有段都是'load'类型 - 我猜这些是来自所有参与文件的.text和.bss/.data段,加上堆栈段.除了这些加载段,有一个音符段,但似乎不包含地图.那么关于哪个文件段对应的信息如何存储在核心文件中?这些"加载"段是否以特定方式格式化以包含文件信息?

gdb coredump elf

14
推荐指数
2
解决办法
2万
查看次数

为什么编译器版本出现在我的ELF可执行文件中?

我最近使用gcc在Debian Linux下编译了一个简单的hello world C程序:

gcc -mtune=native -march=native -m32 -s -Wunused -O2 -o hello hello.c
Run Code Online (Sandbox Code Playgroud)

文件大小为2980字节.我在十六进制编辑器中打开它,我看到以下几行:

GCC: (Debian 4.4.5-8) 4.4.5 GCC: (Debian 4.4.5-10) 4.4.5 .shstrtab .interp .note.ABI-tag .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rel.dyn .rel.plt .init .text .fini .rodata .eh_frame .ctors .dtors .jcr .dynamic .got .got.plt data.data .bss .comment
Run Code Online (Sandbox Code Playgroud)

他们真的需要吗?无法减少可执行文件的大小?

c linux gcc elf

14
推荐指数
3
解决办法
5733
查看次数

ldd不适用于动态链接的二进制文件

我有一个使用一堆.so文件的二进制文件.

bash-3.00$ file foo
foo: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.21, dynamically linked (uses shared libs), not stripped
Run Code Online (Sandbox Code Playgroud)

但是如果我在这个文件上运行ldd,它就无法获取二进制文件所依赖的.so文件.

bash-3.00$ ldd foo
        not a dynamic executable
bash-3.00$
Run Code Online (Sandbox Code Playgroud)

readelf确实显示了二进制文件使用的共享库列表.

bash-3.00$ readelf -d  foo
Dynamic segment at offset 0x17c810 contains 70 entries:

  Tag        Type                         Name/Value
 0x00000001 (NEEDED)                     Shared library: [libdl.so.2]
Run Code Online (Sandbox Code Playgroud)

在这种情况下,为什么ldd无法获取库依赖项?

linux linker shared-libraries elf

14
推荐指数
2
解决办法
2万
查看次数

用法之间的区别.a.out,.ELF,.EXE和.COFF

通过查看问题标题不要误解我 - 我知道它们是什么(可移植可执行文件的格式).但我的兴趣范围略有不同

我的困惑

我参与了重新托管/重新定位最初来自第三方的应用程序.问题是,有时目标代码的格式也是.elf,.COFF格式,仍然说"可执行和可链接".

我主要是Windows用户,并且知道在编译和汇编C/C++代码时,会得到类似于.o或.obj的东西.这是不可执行的(好吧,我从来没有尝试过执行它们).但是,当您完成链接静态和动态库并完成构建时,将显示可执行文件.我的理解是,您可以继续并链接该可执行文件,或者在必要时使用某种形式的脚本"bash"测试它.

但是,在Linux(或类UNIX系统)中,在编译和汇编C/C++代码之后会有.o文件.一旦链接完成,可执行文件就是a.out格式(至少在Linux的Ubuntu发行版中).在其他一些分销商中很可能是.elf.在我的快速网络搜索中,没有任何消息来源提到任何关于.o文件作为可执行文件.

质询

因此我的问题变成了以下几点:

  1. 可移植可执行文件和目标代码的真正定义是什么?

  2. Windows和UNIX平台如何涵盖相同文件格式(.COFF,.elf)下的可执行文件和目标代码.

  3. 我误解了"可链接"吗?我对"可链接"的解释是编译目标代码,然后可以"链接"到其他静态/动态链接库.这是一个愚蠢的想法吗?

  4. 根据问题1.(可能还有2个)我是否需要使用符号表(例如.LUM或.MAP文件)和目标代码?调试符号中的符号,并在重新托管不同计算机上的可执行文件/目标文件时使用它们.

在此先感谢正确的推动.同时,如有必要,我会继续挖掘和更新问题.

UPDATE

我已经设法从某个地方挖出这个 :(似乎很多东西要吞下我.

linker executable coff elf

14
推荐指数
1
解决办法
1万
查看次数

ELF中程序头和节头之间的区别

Q1 ELF中程序头和节头之间有什么区别

Q1.1段和段之间有什么区别?

我相信pheaders只指向部分.

Q2.什么是文件头和程序头之间的差异

根据gnu ld链接器脚本,使用Id:GNU链接器:

PHDRS
{
name type [ FILEHDR ] [ PHDRS ] [ AT ( address ) ]
[ FLAGS ( flags ) ] ;
}
Run Code Online (Sandbox Code Playgroud)

您可以在程序标题类型后面使用FILEHDR和PHDRS关键字来进一步描述该段的内容.FILEHDR关键字表示该段应包含ELF文件头.PHDRS关键字表示该段应包含ELF程序头本身

This is a bit confusing
Run Code Online (Sandbox Code Playgroud)

c arm gnu elf linker-scripts

14
推荐指数
1
解决办法
1万
查看次数