我已经构建了一个像这样的简单程序:
g++ application.cpp -o application.exe
然后执行命令;
ldd application.exe
...
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6
...
Run Code Online (Sandbox Code Playgroud)
我想列出libc库的所有符号:
nm /lib/x86_64-linux-gnu/libc.so.6
nm: /lib/x86_64-linux-gnu/libc.so.6: no symbols
nm --defined-only /lib/x86_64-linux-gnu/libc.so.6
nm: /lib/x86_64-linux-gnu/libc.so.6: no symbols
Run Code Online (Sandbox Code Playgroud)
为什么 nm 报告没有符号?如果 libc.so.6 不是库,而是某种指向实际库的链接,那么我如何才能找到实际库?
单元测试涉及失败的代码路径的最佳方法是什么malloc()?在大多数情况下,它可能并不重要,因为你正在做类似的事情
thingy *my_thingy = malloc(sizeof(thingy));
if (my_thingy == NULL) {
fprintf(stderr, "We're so screwed!\n");
exit(EXIT_FAILURE);
}
Run Code Online (Sandbox Code Playgroud)
但在某些情况下,除了死亡之外你还有其他选择,因为你已经为缓存或其他任何东西分配了一些额外的东西,你可以收回那些记忆.
但是,在那些您可以尝试从失败malloc()中恢复的情况下,您在代码路径中执行的操作非常棘手并且容易出错,这使得测试变得尤为重要.你是怎么做到这一点的?
我试图获取exit()libc中提供的函数的地址(十六进制),但我不知道在哪里以及如何找到它.
任何人都知道找到它的方法请分享一些想法.谢谢!
我-lrt将最后一个链接器标志作为编译器.但仍然得到这个错误.
arif@khost:~/sak/sak.exosip$ gcc eXo_init.c -I/opt/osip2/include -I/opt/exosip/include -L/opt/osip2/lib -L/opt/exosip/lib -leXosip2 -losipparser2 -losip2 -lrt
/opt/osip2/lib/libosip2.so: undefined reference to `clock_gettime'
collect2: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)
手册页说:
NAME
clock_getres, clock_gettime, clock_settime - clock and time functions
SYNOPSIS
#include <time.h>
int clock_getres(clockid_t clk_id, struct timespec *res);
int clock_gettime(clockid_t clk_id, struct timespec *tp);
int clock_settime(clockid_t clk_id, const struct timespec *tp);
Link with -lrt.
Run Code Online (Sandbox Code Playgroud)
所以我有点困惑,我做错了.
我试图在librt.so没有运气的情况下阅读符号:
arif@khost:~/sak/ortp/src/tests$ nm /lib/x86_64-linux-gnu/librt-2.15.so
nm: /lib/x86_64-linux-gnu/librt-2.15.so: no symbols
Run Code Online (Sandbox Code Playgroud)
更新1我无法读取符号的原因librt.so是它们被"剥离".我在哪里可以获得符号名称?
arif@khost:~/sak/ortp/src/tests$ file /lib/x86_64-linux-gnu/librt-2.15.so
/lib/x86_64-linux-gnu/librt-2.15.so: ELF …Run Code Online (Sandbox Code Playgroud) 我正在研究如何在Linux系统上实现TLS(线程本地存储).文档ELF处理线程局部存储解释了程序对线程局部变量的要求如何在ELF二进制文件中编码,以及"运行时"如何处理这些二进制文件.
但是,我不清楚在实践中,设置TLS区域的"运行时"是Linux内核(及其加载ELF二进制文件的代码)还是libc中的一些初始化代码.有人能简单解释一下吗
(背景:我正在尝试静态链接并运行一个应用程序,但它在启动时会出现段错误.在gdb中,我可以看到segfaulting代码是来自libc的一些初始化代码.它试图使用相对于的地址读取静态变量GS,但GS为零.)
我试图捕获libc检测到错误条件时生成的错误消息.例如,我的测试代码:
#include <stdlib.h>
int main()
{
char* p = (char*)malloc(10);
free(p);
free(p);
}
Run Code Online (Sandbox Code Playgroud)
生成此输出
$ ./main
*** Error in `./main': double free or corruption (fasttop): 0x000000000124b010 ***
======= Backtrace: =========
/lib64/libc.so.6(+0x7d1fd)[0x7f8c121291fd]
./main[0x400b86]
/lib64/libc.so.6(__libc_start_main+0xf5)[0x7f8c120cdaf5]
./main[0x400a79]
... <snip>
Run Code Online (Sandbox Code Playgroud)
但是,它不是写入stderr或stdout,而是/ dev/tty(我发现使用strace)
open("/dev/tty", O_RDWR|O_NOCTTY|O_NONBLOCK) = 3
writev(3, [{"*** Error in `", 14}, {"./main", 6}, {"': ", 3}, {"double free or corruption (fastt"..., 35}, {": 0x", 4}, {"00000000011bf010", 16}, {" ***\n", 5}], 7*** Error in `./main': double free or corruption (fasttop): 0x00000000011bf010 ***
) = …Run Code Online (Sandbox Code Playgroud) 究竟SIG_DFL(信号的defaut处理程序)做了什么?我对SIGTSTP很感兴趣.在奇怪的条件下,它有点行为不端.如果一个线程处于TASK_ININTERRUPTBLE状态,我怀疑它做了一些奇怪的事情.
SIG_DFL源代码在哪里?libc库?
谢谢.
当我在 x86-64 linux 上使用 libc 的 system() 函数时,我注意到一个非常奇怪的行为,有时调用system()失败并出现分段错误,这是我在使用gdb.
我注意到在这一行中出现了分段错误:
=> 0x7ffff7a332f6 <do_system+1094>: movaps XMMWORD PTR [rsp+0x40],xmm0
Run Code Online (Sandbox Code Playgroud)
根据手册,这是 SIGSEGV 的原因:
当源或目标操作数是内存操作数时,操作数必须在 16 字节边界上对齐,否则会生成通用保护异常 (#GP)。
再往下看,我注意到我的rsp值确实不是 16 字节填充的(也就是说,它的十六进制表示没有以 结尾0)。rsp在调用之前手动修改权限system实际上使一切正常。
所以我写了以下程序:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
register long long int sp asm ("rsp");
printf("%llx\n", sp);
if (sp & 0x8) /* == 0x8*/
{
printf("running system...\n");
system("touch hi");
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
用gcc 7.3.0编译,果然,观察输出时:
sha@sha-desktop:~/Desktop/tda$ ltrace -f ./o_sample2 …Run Code Online (Sandbox Code Playgroud) 我用 C、Go 和 Rust 编写了简单的代码。
foo.c
#include <stdio.h>
int main()
{
printf("hello\n");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
foo.go
#include <stdio.h>
int main()
{
printf("hello\n");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
foo.rs
package main
import "fmt"
func main() {
fmt.Println("hello");
}
Run Code Online (Sandbox Code Playgroud)
然后我把它们全部建造起来。
fn main() {
println!("hello");
}
Run Code Online (Sandbox Code Playgroud)
他们运行良好。
$ gcc -static -o cfoo foo.c
$ go build -o gofoo foo.go
$ rustc -o rustfoo foo.rs
Run Code Online (Sandbox Code Playgroud)
Rust 可执行文件的二进制文件与其他两个相比太小,因此我怀疑它不是静态可执行文件。
$ ./cfoo; ./gofoo; ./rustfoo
hello
hello
hello
Run Code Online (Sandbox Code Playgroud)
我确认 Rust 不会生成静态可执行文件。
$ ls -l cfoo gofoo rustfoo
-rwxr-xr-x 1 lone …Run Code Online (Sandbox Code Playgroud) 这是一个简单的程序:
void __attribute__ ((constructor)) dumb_constructor(){}
void __attribute__ ((destructor)) dumb_destructor(){}
int main() {}
Run Code Online (Sandbox Code Playgroud)
我用以下标志编译它:
g++ -O0 -fverbose-asm -no-pie -g -o main main.cpp
Run Code Online (Sandbox Code Playgroud)
我检查与gdb那个__libc_csu_init呼唤我标记瓦特/构造函数:
Breakpoint 1, dumb_constructor () at main.cpp:1
1 void __attribute__ ((constructor)) dumb_constructor(){}
(gdb) bt
#0 dumb_constructor () at main.cpp:1
#1 0x000000000040116d in __libc_csu_init ()
#2 0x00007ffff7abcfb0 in __libc_start_main () from /usr/lib/libc.so.6
#3 0x000000000040104e in _start ()
Run Code Online (Sandbox Code Playgroud)
我认为该destructor属性意味着dumb_destructor()将在 期间调用__libc_csu_fini,但这并没有发生:
Breakpoint 1, dumb_destructor () at main.cpp:3
3 void __attribute__ ((destructor)) dumb_destructor(){} …Run Code Online (Sandbox Code Playgroud)