我试图在c中挂钩printf
函数并实现一个非常相似的函数,只打印到stderr
流。
printf代码:
int printf (const char *format, ...)
{
va_list arg;
int done;
va_start (arg, format);
done = vfprintf (stdout, format, arg);
va_end (arg);
return done;
}
我将stdout更改为stderr但是当使用> /dev/null
(将stdout
重定向到null)运行时,我仍然看不到输出。运行ltrace时我可以看到它调用puts而不是printf,我认为这是问题所在。
答案 0 :(得分:1)
根据ISO / IEC 9899:201x重新定义像printf
这样的保留标识符会导致未定义的行为:
7.1.3.2 ...如果程序在保留的上下文中声明或定义标识符(除了允许的标识符) 通过7.1.4),或者将保留的标识符定义为宏名, 行为未定义。
所以像P.P.指出编译器通过用printf
替换它们来优化对puts
的某些调用是完全合法的,因为如果未重新定义printf
并且UB规则(意味着什么),则可观察行为是相同的可以发生)如果你重新定义它就适用。
答案 1 :(得分:0)
所以我想出来..上面的代码很好,预装很好,而且正如我所说的那样,put被称为而不是printf。演示LD_PRELOAD的简单Hello World程序如下所示:
printf("Hello World\n");
当我删除\ n它工作正常,并没有调用put! 有关此问题的更多信息,请访问:Problems on injecting into printf using LD_PRELOAD method