Что заставляет sprof жаловаться на "несогласованность, обнаруженную ld.so"?

Я пытаюсь использовать sprof для профилирования некоторого программного обеспечения (ossim), где почти весь код находится в общей библиотеке. Я создал файл профилирования, но когда я запускаю sprof, я получаю следующую ошибку:

> sprof /home/eca7215/usr/lib/libossim.so.1 libossim.so.1.profile -p > log
Inconsistency detected by ld.so: dl-open.c: 612: _dl_open: Assertion `_dl_debug_initialize (0, args.nsid)->r_state == RT_CONSISTENT' failed!

Последующие инструкции сказали, что мне нужна версия libc как минимум 2,5-34, у меня есть версия libc версии 2.12.2 (Gentoo, kernel 2.6.36-r5).

Я не могу найти никакого объяснения относительно того, что означает ошибка или (что более интересно), как ее исправить, но только половину релевантных результатов Google для ошибки в старой версии Skype.

Ответы

Ответ 1

Мне стало немного любопытно, так как это все еще нарушено в OpenSuse 12.x. Я бы подумал, что ошибка, о которой первоначально сообщалось в '09, или около того, была бы исправлена ​​к настоящему времени. Наверное, никто не использует sprof. (или, может быть, dl-open настолько хрупок, что люди боятся дотронуться до него: -)

Проблема сводится к флагу __RTLD_SPROF, используемому в качестве аргумента для dlopen. Возьмите любую простую программу, которая вызывает dlopen, или этот флаг для второго arg, и вы получите то же неудачное утверждение. Я использовал примерную программу внизу http://linux.die.net/man/3/dlopen в качестве примера

handle = dlopen(argv[1], RTLD_LAZY | __RTLD_SPROF);

Из того, что я могу сказать по быстрому рассмотрению dl-open.c, этот флаг коротко замыкает некоторые из того, что делает dl_open. Таким образом, r_flag, указанный в утверждении, не устанавливается в RT_CONSISTENT.

Ответ 2

Если вы используете Docker, может быть другое объяснение. В моем случае данные профилирования были сгенерированы из процесса, выполняющегося внутри контейнера Docker, я попытался запустить sprof изнутри контейнера и получил ту же ошибку, как описано в вопросе. Запуск sprof от хоста (вместо контейнера) решил это.