如何在 LD_PRELOADed 共享库中只运行一次代码?

问题描述 投票:0回答:1

下面的代码演示了使用

LD_PRELOAD
时,可以在同一个进程中多次加载库(多次调用构造函数,多次初始化静态数据)。

#define _GNU_SOURCE #include <stdio.h> #include <unistd.h> #include <stdbool.h> extern bool initialized = false; void __attribute__ ((constructor)) setup() { printf("constructor %d %d %d\n", getpid(), gettid(), initialized); initialized = true; }
可以使用以下命令运行实验:

$ gcc -Wall -shared -fPIC -o libtest.so lib.c $ env LD_PRELOAD=$PWD/libtest.so sh -c "$cmd" constructor 98928 98928 0 constructor 98928 98928 0 ... rest of output of $cmd
注意PID是一样的;这不是分叉造成的问题。请注意, 

initialized

 变量为 0,大概是因为每次加载库时,加载器都会将静态部分放入新的内存中。我知道将 
sh -c "$cmd"
 替换为 
$cmd
 
会导致库在这种特殊情况下仅加载一次,但通常不会($cmd
 本身可能是对 
sh -c
 的调用)。

如何在

LD_PRELOAD

ed 库中只运行一次代码?人们想要使用 
LD_PRELOAD
 来完成的许多任务都需要进程全局数据。

c linux shared-libraries posix ld-preload
1个回答
0
投票
当您执行

sh

时,库将被加载,并且构造函数将运行。然后,由于 
-c "$cmd"
,shell 调用 
exec
 例程,用新程序完全替换该进程。几乎先前程序的所有内容都被擦除,包括加载的库。然后新程序启动,因此库再次加载,构造函数再次运行。它不会在同一个程序中运行构造函数两次。

我知道将

sh -c "$cmd"

 替换为 
$cmd
 
会导致库在这种特殊情况下仅加载一次,…

如何在

LD_PRELOAD
ed 库中只运行一次代码?

在书写时,将

sh -c "$cmd"
替换为
$cmd

$cmd
本身可以是对
sh -c

的调用

不,不是。

$cmd
本身告诉您当前的 shell 执行
$cmd
sh -c $cmd
告诉您当前的 shell 创建一个新 shell 并让它执行
$cmd

© www.soinside.com 2019 - 2024. All rights reserved.