c++ - 如何让 GDB 自动停止解析共享库中的符号
问题描述
我创建了一个简单的程序,在共享库中调用 foo 函数。它会这样调用:
0000000000001169 <main>:
1169: f3 0f 1e fa endbr64
116d: 55 push %rbp
116e: 48 89 e5 mov %rsp,%rbp
1171: e8 ea fe ff ff callq 1060 <_Z3foov@plt>
当我查看 foo@plt 时,它看起来像
0000000000001060 <_Z3foov@plt>:
1060: f3 0f 1e fa endbr64
1064: f2 ff 25 5d 2f 00 00 bnd jmpq *0x2f5d(%rip) # 3fc8 <_Z3foov>
106b: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
奇怪的是,当我运行该程序的 gdb 时,*0x2f5d(%rip) 已经包含 foo 函数的地址。我想知道它是如何自动绑定的。
nopl 0x0(%rax,%rax,1)
另外,指令的目的是什么?
更新
我意识到我的程序是使用完整的 RELRO 选项编译的。于是我又用norelro选项编译了一遍(-Wl,-z,norelro,用checksec确认不是RELRO),这样就可以通过gdb观察惰性绑定了。但是,似乎 gdb 在 main 启动之前会自动解析所有动态符号。如何让 gdb 不这样做?
更新 2
// foo.h
int foo();
// foo.cc
#include "bar.h"
int foo() {
bar();
return 1;
}
// bar.h
void bar();
// bar.cc
void bar() {}
// main.cc
#include "bar.h"
#include "foo.h"
int main() {
bar();
foo();
}
我按如下方式创建了共享库。
$ g++ -c -fpic -g foo.cc
$ g++ -c -fpic -g bar.cc
$ g++ -shared foo.o bar.o -o -g libfoobar.so
并将其链接到main。
g++ -g -Wl,-z,norelro main.cc libfoobar.so -o main
checksec 告诉我No RELRO
是指定的。
$ checksec --file=main
RELRO STACK CANARY NX PIE RPATH RUNPATH Symbols FORTIFY Fortified Fortifiable FILE
No RELRO No canary found NX enabled PIE enabled No RPATH No RUNPATH 71 Symbols No 0 0 main
解决方案
推荐阅读
- node.js - 使用 NPM 模块
- docker - Apache 反向代理 503 服务不可用
- encoding - FFMPEG:无法在过滤器支持的格式之间进行转换 - 重新初始化过滤器时出错
- python - GROK LEARNING:密码学多密钥
- angular - 'node-sass' 的使用已被弃用,将在未来的主要版本中删除
- javascript - 如何使用 AJAX 管理 DataTables 中的子行
- flutter - 为什么使flutter_map居中不起作用?
- python - 获取 HTML 表格行数据到 Flask 函数
- reactjs - React Native to firestore:Firestore(8.2.1):连接WebChannel传输错误
- deep-learning - 在尝试训练 SeGAN 模型时尝试调用本地“回调”(零值)错误