减少程序的 sleep() 函数

Dan*_*tti 3 linux sleep

我有一个为 Linux 开发的二进制程序,它从服务器的网络流中读取行。它的通信是加密的,我需要很长时间才能弄清楚,所以我无法重写它。

输出每一行后,程序调用nanosleep(100000000)(我发现这个使用strace)但是,当服务器快速连续发送多行时,实际流和输出之间有很大的延迟。

由于我没有程序的源代码,我的问题是:有没有办法减少这个软件的睡眠时间?“加速”吗?

供参考,程序是Punkbuster的PBUcon

rod*_*igo 7

你可以试试 LD_PRELOAD 技巧:

/* nosleep.c */
#include <time.h>
#include <unistd.h>

int sleep(unsigned int seconds)
{
    return 0;
}
int usleep(useconds_t usec)
{
    return 0;
}
int nanosleep(const struct timespec *req, struct timespec *rem)
{
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

然后编译:

$ gcc -o libnosleep.so -shared nosleep.c -fpic
Run Code Online (Sandbox Code Playgroud)

然后运行你的程序:

$ LD_PRELOAD=./libnosleep.so pbucon
Run Code Online (Sandbox Code Playgroud)

您应该注意以下几点:

  1. 它将替换对 的每次调用nanosleep,不仅是您不喜欢的调用,而且会产生微妙的不良影响。如果您觉得需要,您可以检查参数的特定值。
  2. 它不适用于 suid/sgid 程序。
  3. 它仅适用于动态链接的程序,不适用于静态链接的程序。

更新:如果要将调用链接到原始函数,可以执行以下操作:

#define _GNU_SOURCE 

#include <stdio.h>
#include <unistd.h>
#include <dlfcn.h>

int usleep(useconds_t sec)
{
    typedef int (*usleep_f)(useconds_t);
    static usleep_f real_usleep = NULL;
    if (!real_usleep)
        real_usleep = (usleep_f)dlsym(RTLD_NEXT, "usleep");

    printf("%d\n", (int)sec);

    if (...)
        return real_usleep(sec);
    else
        return 0;
}
Run Code Online (Sandbox Code Playgroud)

如果您想避免 GNU 扩展(RTLD_NEXT是一个),您必须找到包含该函数的共享库的名称,例如:

$ objdump -p pbucon.run | grep NEEDED
NEEDED           libc.so.6
Run Code Online (Sandbox Code Playgroud)

然后,在函数中执行:

    if (!real_usleep)
    {
        void *libc_so = dopen("libc.so.6", RTLD_GLOBAL);
        real_usleep = (usleep_f)dlsym(libc_so, "usleep");
    }
Run Code Online (Sandbox Code Playgroud)