Невозможно распечатать в файл из общего объекта

Я уже видел вопросы, подобные этому, здесь ранее, но я не смог решить свою проблему из ответов на них.

У меня есть файл 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 (будет расширена позже) должна заменить malloc stdlib.h в другой фиктивной программе, исходный код которой находится в 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 работает внутри общего объекта, но только внутри функции настройки, если я вызываю printf внутри malloc программа segfaults. В попытке хотя бы выяснить, какой терминал 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 manpage, эта вторая строка вывода должна быть невозможной. Я совершенно не понимаю что-то здесь?

1 ответ

Вот что я запустил, создал из вашего кода, и он работал отлично, генерируя файл: 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

Другие вопросы по тегам