gpt4 book ai didi

c++ - clock_gettime 在带有 CLOCK_PROCESS_CPUTIME_ID 的 chrooted Debian eclipse 刻中失败

转载 作者:太空宇宙 更新时间:2023-11-04 12:06:01 25 4
gpt4 key购买 nike

我在 Ubuntu 12.04(64 位)下设置了一个 chrooted Debian Etch(32 位),看起来 clock_gettime() 与 CLOCK_MONOTONIC 一起工作,但在 CLOCK_PROCESS_CPUTIME_ID 和 CLOCK_THREAD_CPUTIME_ID 上都失败了。 errno 设置为 EINVAL,根据手册页,这意味着“此系统不支持指定的 clk_id。”

所有三个时钟在 chrooted Debian 和 64 位 chrooted Debian etch 之外工作正常。

有人可以向我解释为什么会出现这种情况以及如何解决吗?

非常感谢。

最佳答案

我还不知道原因,但我有不适合评论框的想法。

首先,您可以通过将测试程序编译为 C 而不是 C++ 并且不将其链接到 libpthread 来简化测试程序。 -lrt 应该足以获取 clock_gettime。此外,使用 -static 编译它可以使跟踪更容易,因为动态链接器启动的东西不会在那里。

静态链接甚至可能会改变 clock_gettime 的行为。值得一试,看看它是否能解决该错误。

我想看到的另一件事是这个 vdso 绕过测试程序的输出:

#define _GNU_SOURCE
#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <sys/syscall.h>

int main(void)
{
struct timespec ts;
if(syscall(SYS_clock_gettime, CLOCK_PROCESS_CPUTIME_ID, &ts)) {
perror("clock_gettime");
return 1;
}
printf("CLOCK_PROCESS_CPUTIME_ID: %lu.%09ld\n",
(unsigned long)ts.tv_sec, ts.tv_nsec);
return 0;
}

使用和不使用-static,如果失败,添加strace

更新(其实跳过这个,进入第二次更新)

几个更简单的测试思路:

  1. 通过将 -m32 添加到 gcc 命令,在 Ubuntu 主机系统中编译并运行 32 位测试程序。可能是内核的 32 位兼容模式导致了该错误。如果是这种情况,那么无论链接到哪个 libc,32 位版本都会失败。
  2. 将您在 Debian 下编译的非静态测试程序复制到 Ubuntu 主机系统并尝试在那里运行它们。行为的变化将指向 libc 作为原因。

然后是困难的时候了。查看反汇编代码并可能在 gdb 中单步执行它。我不想让您自己执行此操作,而是希望获取您正在运行的代码的拷贝。在我能得到的地方上传一个静态编译的失败测试程序。您的内核提供的 32 位 vdso 拷贝也可能很有趣。要提取 vdso,请运行以下程序(在 32 位 chroot 中编译),这将创建一个名为 vdso.dump 的文件,并上传该文件。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static int getvseg(const char *which, const char *outfn)
{
FILE *maps, *outfile;
char buf[1024];
void *start, *end;
size_t sz;
void *copy;
int ret;
char search[strlen(which)+4];

maps = fopen("/proc/self/maps", "r");
if(!maps) {
perror("/proc/self/maps");
return 1;
}
outfile = fopen(outfn, "w");
if(!outfile) {
perror(outfn);
fclose(maps);
return 1;
}

sprintf(search, "[%s]\n", which);
while(fgets(buf, sizeof buf, maps)) {
if(strlen(buf)<strlen(search) ||
strcmp(buf+strlen(buf)-strlen(search),search))
continue;
if(sscanf(buf, "%p-%p", &start, &end)!=2) {
fprintf(stderr, "weird line in /proc/self/maps: %s", buf);
continue;
}
sz = (char *)end - (char *)start;
/* copy because I got an EFAULT trying to write directly from vsyscall */
copy = malloc(sz);
if(!copy) {
perror("malloc");
goto fail;
}
memcpy(copy, start, sz);
if(fwrite(copy, 1, sz, outfile)!=sz) {
if(ferror(outfile))
perror(outfn);
else
fprintf(stderr, "%s: short write", outfn);
free(copy);
goto fail;
}
free(copy);
goto success;
}
fprintf(stderr, "%s not found\n", which);

fail:
ret = 1;
goto out;
success:
ret = 0;
out:
fclose(maps);
fclose(outfile);
return ret;
}

int main(void)
{
int ret = 1;
if(!getvseg("vdso", "vdso.dump")) {
printf("vdso dumped to vdso.dump\n");
ret = 0;
}
if(!getvseg("vsyscall", "vsyscall.dump")) {
printf("vsyscall dumped to vsyscall.dump\n");
ret = 0;
}
return ret;
}

更新2

我通过下载 etch libc 复制了这个。这绝对是 glibc 愚蠢造成的。而不是 clock_gettime 的简单系统调用包装器,它有一大堆预处理器意大利面条,最终导致“你不能使用我们没有预先批准的 clockid”。你不会让它与那个旧的 glibc 一起工作。这让我们想到了一个我不想问的问题:你为什么要尝试使用 Debian 的过时版本?

关于c++ - clock_gettime 在带有 CLOCK_PROCESS_CPUTIME_ID 的 chrooted Debian eclipse 刻中失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12064404/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com