我以前在这里看到过与此类似的问题,但我无法从这些答案中解决我的问题。
我有一个文件libfoo.c
,我正在从中创建一个共享对象。使用 gcc's __attribute__((constructor))
,我想在加载此共享对象时向文件打印一条消息:
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
static char *term = NULL;
static void init (void) __attribute__((constructor));
static void
init (void)
{
FILE *f = fopen ("lib.log", "w");
if (f)
{
if (isatty (STDOUT_FILENO))
{
char *tmp = ttyname (STDERR_FILENO);
if (tmp && *tmp)
{
term = strdup (tmp); // nevermind the memory leak
fprintf (f, "Found terminal %s\n", term);
}
}
else
fprintf (f, "Failed to find terminal\n");
fclose(f);
}
}
void *
malloc (size_t size)
{
return NULL;
}
虚拟 malloc 实现(稍后将扩展)应在另一个虚拟程序中替换 stdlib.h 的 malloc,其源代码位于main.c
:
#include <stdlib.h>
int main (void)
{
char *m = malloc(1024);
(void)m;
return 0;
}
我正在编译和链接这两个文件,如下所示:
gcc -o main main.c
gcc -fpic -shared -o libfoo libfoo.c
然后当我执行以下操作时,不会创建任何文件,也不会记录任何输出:
LD_PRELOAD=$(readlink -f libfoo) ./main
这里发生了什么?作为旁注:我如何尝试使用 ltrace 调试这样的问题?ltrace "LD_PRELOAD=... ./main"
不是一个有效的命令。
编辑:这里发生了什么?如果我在程序段错误内调用,它似乎至少printf
在共享对象内有效,但只能在设置函数内工作。在试图至少弄清楚连接到哪个终端时,我做了以下操作(在 setup 函数中):printf
malloc
stdout
// ...
char buf[100];
buf[readlink ("/proc/self/fd/1", buf, 100)] = '\0';
printf ("STDOUT (buf): %s\n", buf);
char *tmp = ttyname (1);
printf ("STDOUT (ttyname): %s, %s\n", tmp, strerror (errno));
// ...
这打印:
STDOUT (buf): /dev/pts/1
STDOUT (ttyname): (null), Success
根据ttyname
手册页,第二行输出应该是不可能的。我在这里完全误解了什么吗?