ld_preload printf使用stderr而不是stdout

时间:2016-07-27 11:11:44

标签: c unix printf ld-preload

我试图在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,我认为这是问题所在。

2 个答案:

答案 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