当我编写一个要与LD_PRELOAD一起使用的库时,我如何调试它的__attribute__((__constructor__))个函数?它们似乎总是在gdb停止进程之前运行.作为MCVE,运行以下命令:

cat > preflight.c <<EOF
#include <stdio.h>
#include <stdlib.h>

__attribute__((__constructor__))
void preflight(void) {
    puts("Exiting from preflight");
    exit(42);
}
EOF
gcc -g -fPIC -shared preflight.c -o preflight.so
gdb /bin/true -ex 'set environment LD_PRELOAD ./preflight.so' \
              -ex 'set breakpoint pending on' \
              -ex 'break preflight' \
              -ex 'starti'

Gdb输出的结尾如下所示:

Function "preflight" not defined.
Breakpoint 1 (preflight) pending.
Starting program: /usr/bin/true 
Exiting from preflight
During startup program exited with code 42.
(gdb) 

注意到preflight函数在gdb停止程序之前运行,尽管我试图在它上面设置一个断点,并且我使用了starti,它应该在第一条指令时中断.我必须做什么不同的操作才能让gdb突破preflight函数?

推荐答案

这是因为在默认情况下,gdb使用一个shell 来启动正在调试的程序,并且提供给set environment的环境变量也适用于该shell ,所以我的preflight函数在那里运行.Gdb不调试shell ,所以当它在那里运行时,它没有停止它.如何解决此问题有两种 Select :

  1. 一百.
  2. set exec-wrapper env LD_PRELOAD=./preflight.so,而不是set environment LD_PRELOAD ./preflight.so.

参考文献:GDB的文档,第4.2 Starting your Program4.4 Your Program's Environment节.

C++相关问答推荐

为指针 struct 创建宏

C如何显示字符串数组中的第一个字母

了解一些CLIPS原语数据类型

与unions 的未定义行为

如何使fputs功能提示错误输入并要求用户重新输入.程序停止而不是请求新的输入

在一个小型玩具项目中实现终端历史记录功能

为什么我一直收到分段错误?

向上强制转换C中的数值类型总是可逆的吗?

如何在C中打印包含扫描字符和整数的语句?

如何在C++中处理按键

在移动数组元素时获得意外输出

我的C函数起作用了,但我不确定为什么

致命错误:ASM/rwan ce.h:没有这样的文件或目录.符号链接还不够

在C中创建任意类型的只读指针参数

错误...的多个定义(&Q)首先在这里定义&

在运行时判断C/C++指针是否指向只读内存(在Linux操作系统中)

具有正确标头的C struct 定义问题

在哪里可以找到叮当返回码的含义?

gdb - 你能找到持有内部 glibc 锁的线程吗?

函数指针作为函数参数 - 应该使用 const 吗?