簡體   English   中英

無法從共享對象打印到文件

[英]Unable to print to file from shared object

我之前在這里看到過與此問題類似的問題,但是我無法從這些問題的答案中解決我的問題。

我有一個文件libfoo.c將從中創建一個共享庫。 使用gcc的__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實現(將在以后擴展)應在另一個源代碼位於main.c虛擬程序中替換stdlib.h的malloc:

#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在共享庫中起作用,但僅在設置函數內部起作用,如果我在malloc程序段錯誤中調用printf話。 在嘗試至少確定連接到哪個終端stdout過程中,我執行了以下操作(在setup函數內部):

// ...

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聯機幫助頁,輸出的第二行應該是不可能的。 我在這里完全誤解了嗎?

這是我根據您的代碼創建的運行文件,它運行完美,生成了一個文件: lib.log

文件內容:lib.log

Found terminal /dev/pts/1

現在,我運行的代碼是:

#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", temp);
            }
        }

        else
            fprintf (f, "Failed to find terminal\n");

      fclose(f);
   }

   else
   {
       perror( "fopen failed" );
   }
}


void *
myMalloc (size_t size)
{
    (void)size;
    return NULL;
}


int main (void)
{
    char *m = myMalloc(1024);
    (void)m;
    return 0;
}

當然,您發布的代碼缺少頭文件。 這樣的頭文件應該由main.c文件和libfoo.c文件引用/包含。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM