2015-11-18 4 views
2

Я пытаюсь понять, как делает всемирную программу приветствия работы:Как понять перекрестную ссылку glibc?

#include <stdio.h> 

int main(int argc, char **argv) { 
    printf("Hello World!"); 
    return 0; 
} 

Большинство из них является прямым, за исключением printf части. Я не знаю, как это работает. Чтобы понять это, я искал glibc cross reference и нашел this page.

Затем я искал printf, и он вернул мне много results.

Теперь какая из этих printf s моя программа использует? Как я могу это определить?

Кроме того, например, при открытии first result в этой странице, функция в printf функции приводит меня к __printf_chk, где функция в __printf_chk приводит меня к __nldbl___vfprintf_chk, где функция в __nldbl___vfprintf_chk приводит меня к __vfprintf_chk, где функция __vfprintf_chk приводит меня снова __nldbl___vfprintf_chk, что создает бесконечную рекурсию. Что происходит?

Итак, как я должен отслеживать источник данной функции/исходного кода?

+0

«Теперь, который один из этих printfs моя программа использует? Как я могу определить это?» Вы должны выяснить, как построена библиотека. Это зависит в основном от того, как вызывается компилятор, который определен в Make-файлах. Которые, вероятно, так же нечитаемы. Разве это не весело? (Spoiler: glibc не забава.) –

+0

Еще один спойлер: вы в конечном итоге попадете в определение [vfprintf в stdio-common/vfprintf.c] (http://osxr.org/glibc/source/stdio- common/vfprintf.C# 0221), но чтобы увидеть взаимосвязь между ними и функциями, такими как '__printf', вам придется пробираться через большой суп макросов препроцессора и деклараций атрибутов GCC. –

+0

@ Rhymoid Является ли причина для всех этих способов создания/сохранения переносимости? – Utku

ответ

0

У меня нет полного ответа, но я не могу оставить комментарий. Похоже, что __vfprintf_chk вызывает vfprintf, который, как представляется, имеет псевдоним _IO_vfprintf_internal в /stdio-common/vfprintf.c. Я не знаю происхождение последней функции, но я не вижу здесь бесконечного цикла?

+0

[На этой странице] (http://osxr.org/glibc/source/sysdeps/ieee754/ldbl-opt/nldbl-vfprintf_chk.c#0005), '__vfprintf_chk' вызывает' __nldbl ___ vfprintf_chk'. – Utku

+0

Я понимаю, что вы имеете в виду. Похоже, я не буду очень помогать, и я не знаю, как рекурсия, которую вы упомянули, разрешена, но printf, похоже, определен [здесь] (http://osxr.org/glibc/source/stdio-common /printf.c).Выяснение того, какой из них будет использоваться, потребует копания, в которую компилируется/связана система сборки, не знаю намного больше. – tauroid

0

Реализация printf находится в stdio-common/printf.c

int 
__printf (const char *format, ...) 
{ 
    va_list arg; 
    int done; 

    va_start (arg, format); 
    done = vfprintf (stdout, format, arg); 
    va_end (arg); 

    return done; 
} 

который называет vfprintf

+1

Как я должен знать, что он вызывает _that_ 'printf', а не другие? – Utku

+1

Это основная часть меня смущает. Например, когда вы смотрите 'vfprintf' на странице перекрестных ссылок, вы получаете около десятка [результатов] (http://osxr.org/glibc/ident?_i=vfprintf), где 3 из них указаны как функция определения. Ваша ссылка указывает на определение второй функции среди этих результатов, но как я должен знать, что вызывается второй 'vprintf', а не 2 других? – Utku

+0

Нет простого правила - вам, возможно, придется проверить каждый вариант. 'glibc' довольно плотный из-за требований к переносимости и совместимости. Тем не менее, простой способ отсеивать некоторые опции - это посмотреть на пути к файлам и имена файлов. '__printf_chk' выводит вас в каталог' sysdep' - вам не нужно входить в эти типы каталогов для основных реализаций. – rohit89