相关疑难解决方法(0)

什么是LD_PRELOAD技巧?

我最近在proggit看到了它的引用,并且(截至目前)它没有被解释.

我怀疑可能是它,但我不确定.

c linux environment-variables

321
推荐指数
6
解决办法
29万
查看次数

LD_PRELOAD无法按预期工作

考虑以下库,可以在任何程序执行之前预先加载:

// g++ -std=c++11 -shared -fPIC preload.cpp -o preload.so
// LD_PRELOAD=./preload.so <command>
#include <iostream>

struct Goodbye {
    Goodbye() {std::cout << "Hello\n";}
    ~Goodbye() {std::cout << "Goodbye!\n";}
} goodbye;
Run Code Online (Sandbox Code Playgroud)

问题是,虽然goodbye总是调用全局变量的构造函数,但是没有为某些程序调用析构函数,例如ls:

$ LD_PRELOAD=./preload.so ls
Hello
Run Code Online (Sandbox Code Playgroud)

对于其他一些程序,析构函数按预期调用:

$ LD_PRELOAD=./preload.so man
Hello
What manual page do you want?
Goodbye!
Run Code Online (Sandbox Code Playgroud)

你能解释为什么在第一种情况下没有调用析构函数吗?编辑:上面的问题已经得到解答,那就是程序可能会使用_exit(),abort()来退出.

然而:

有没有办法在预加载的程序退出时强制调用给定的函数?

c++ linux gcc ld ld-preload

25
推荐指数
2
解决办法
2336
查看次数

有没有办法标记使用非重入C库调用?

我正在研究一个多线程的项目,并且想知道是否有办法让编译器标记使用对C库的非重入调用(例如strtok_r的strtok intsead)?如果没有,是否有一个不可重入的调用列表,所以我可以定期查看我的代码库?

一个相关的问题是,是否有办法标记3d方库使用非重入调用.

我假设重入意味着线程安全,但不一定反过来.是否有充分的理由在线程项目中使用非重入调用?

c c++ linux multithreading reentrancy

12
推荐指数
1
解决办法
1255
查看次数

这是拦截系统调用的好方法吗?

我正在写一个工具.该工具的一部分是它能够记录系统调用的参数.好吧,我可以ptrace用于此目的,但ptrace速度很慢.我想到的一种更快的方法是修改glibc.但这变得越来越困难,因为gcc神奇地将自己的内置函数作为系统调用包装器插入,而不是使用glibc中定义的代码.使用-fno-builtin也没有帮助.

所以我提出了编写共享库的想法,其中包括每个系统调用包装器,例如mmap然后在调用实际系统调用包装器函数之前执行日志记录.例如,mmap下面给出了我的样子的伪代码.

int mmap(...)
{
 log_parameters(...);
 call_original_mmap(...);
 ...
}
Run Code Online (Sandbox Code Playgroud)

然后我可以使用LD_PRELOAD首先加载这个库.你觉得这个想法会起作用,还是我错过了什么?

c linux gcc glibc x86-64

12
推荐指数
1
解决办法
1802
查看次数

在unix环境中拦截系统调用的可能方法有哪些?

在unix环境中拦截系统调用的可能方法有哪些?我想在AIX上做.

谢谢

unix system-calls

6
推荐指数
1
解决办法
1175
查看次数

防止重用文件描述符

无论如何在Linux(或更一般地说在POSIX OS中)保证在程序执行期间,即使文件被关闭而另一个文件被打开,也不会重复使用文件描述符?我的理解是,这种情况通常会导致已关闭文件的文件描述符被重新分配给新打开的文件.

我正在开发一个I/O跟踪项目,如果我可以假设在open()/ fopen()调用后,该文件描述符的所有后续I/O都是同一个文件,那么它会让生活更简单.

我将采用编译时或运行时解决方案.

如果这是不可能的,我可以做我自己的会计,当我处理跟踪文件(注意所有的打开和关闭通话的位置),但我更愿意被跟踪程序的执行过程中压制该问题.

c linux io posix

5
推荐指数
1
解决办法
3218
查看次数

在不修改内核的情况下拦截系统调用的最小开销方式

我所知道的拦截系统调用的方法如下。

  1. 使用ptrace,但这似乎有很高的开销。据我所知,像strace这样的工具也在内部使用ptrace。
  2. 使用内核模块来改变系统调用表,但据我所知,这种方法在后来的linux内核中不再可行。
  3. 使用 LD_PRELOAD。但是,如果例如您直接进行系统调用而不使用该系统调用的一些包装库函数,这将不起作用。

所以你看到上面提到的所有方法都有缺陷。所以我的问题是在不修改内核和最小开销的情况下拦截系统调用的方法是什么。

c linux gcc x86-64 system-calls

5
推荐指数
1
解决办法
1988
查看次数

eBPF可以修改系统调用的返回值或参数吗?

为了模拟某些行为,我想将探测附加到系统调用,并在传递某些参数时修改返回值.或者,在函数处理之前修改函数的参数也就足够了.

这可能与BPF有关吗?

linux system-calls bpf ebpf

5
推荐指数
2
解决办法
1595
查看次数