代码之家  ›  专栏  ›  技术社区  ›  Pavel Kirienko

用uu属性uuu((构造函数))声明的函数使用LD\u PRELOAD调用了多次

  •  0
  • Pavel Kirienko  · 技术社区  · 5 年前

    #include <unistd.h>
    #include <stdio.h>
    
    static void init(void) __attribute__((constructor));
    static void init(void)
    {
        fprintf(stderr, "pid=%u\n", (unsigned) getpid());
    }
    

    在AMD64计算机上使用GCC 10生成:

    gcc -shared -fPIC lib.c
    

    运行一个简单的过程来验证:

    $ LD_PRELOAD=`realpath a.out` ls
    pid=15771
    a.out  lib.c
    

    线路 pid=15771 打印人 init()

    现在,重复一个生成子线程和线程的复杂过程:

    $ LD_PRELOAD=`realpath a.out` python3
    pid=15835
    pid=15835
    pid=15835
    pid=15835
    pid=15839
    pid=15844
    pid=15835
    pid=15835
    pid=15846
    pid=15846
    pid=15847
    pid=15847
    pid=15849
    pid=15849
    pid=15851
    pid=15852
    pid=15853
    pid=15853
    pid=15856
    pid=15857
    pid=15857
    pid=15858
    pid=15858
    pid=15861
    pid=15862
    pid=15862
    pid=15865
    pid=15868
    pid=15835
    Python 3.8.2 (default, Apr 19 2020, 18:33:14) 
    [GCC 9.3.0] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> 
    

    注意有重复的条目,如 pid=15835 ,表示 已对某些进程执行多次。

    0 回复  |  直到 5 年前
        1
  •  1
  •   Florian Weimer    5 年前

    当Python解释器启动时,Python安装会执行一些程序。如果使用替换进程映像 execve ,进程ID不会更改,但为新进程映像运行构造函数。

    $ LD_PRELOAD=`realpath a.out` bash -c 'exec /bin/true'
    

    您可以通过调用 strace

    $ strace -f -E LD_PRELOAD=`realpath a.out` -eexecve bash -c 'exec /bin/true'
    execve("/usr/bin/bash", ["bash", "-c", "exec /bin/true"], 0x55b275d8b830 /* 29 vars */) = 0
    pid=801315
    execve("/bin/true", ["/bin/true"], 0x5564dedbeb80 /* 29 vars */) = 0
    pid=801315
    +++ exited with 0 +++