Как найти функцию main(...) моей программы?
в настоящее время я переношу проект с несколькими сотнями файлов кода и зависимостей на несколько сторонних библиотек в Mac Os. Я, наконец, дошел до того, что программа компилируется без предупреждений или ошибок, но, похоже, не выполняет мою собственную основную функцию.
вместо этого он, похоже, выполняет какую-то другую основную функцию, которая, похоже, принадлежит третьей стороне. Эта функция записывает некоторые диагностические данные в консоль и завершает работу после этого:
(gdb) continue
Current language: auto; currently c++
//
// This is an automatically generated file.
// Do not edit.
//
const unsigned short expTable[] =
{
0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00,
...
0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00,
};
Debugger stopped.
Program exited with status value:0.
Я не могу использовать отладчик, чтобы узнать, где находится эта основная функция, потому что, хотя трассировка стека кажется допустимой, gdb не показывает мне правильный номер строки и имя файла для каждой записи стека (см. это нерешенный вопрос для деталей).
поиск занял несколько минут, но не возвращает никаких результатов.
мой проект использует SDL среди других библиотек, но я награда SDL_Main() и основной проблемы и построили мой проект поверх прекрасно работающего шаблона проекта SDL. Поэтому я совершенно уверен, что моя собственная основная функция действительна.
у вас есть идеи, что может быть не так? В настоящее время у меня нет идей о том, как найти и удалить основную функцию rogue.
спасибо,
Эдриан
EDIT: как я только что узнал, я сделал ошибку при поиске файлов файлов со строкой " это автоматически сгенерированный." Я только что нашел несколько десятков файлов с той же строкой, все принадлежащие FreeImage, одной из сторонних библиотек, которые я использую. Таким образом, проблема, похоже, связана с FreeImage, но я все еще не уверен, как действовать, поскольку я скомпилировал Freeimage как библиотеку с вложенным файлом macOS makefile и включил только библиотеку. Я попытаюсь восстановить более новую версию FreeImage и посмотреть, исправила ли это мою проблему.
10 ответов
у вас есть несколько основных в двоичной? Попробуйте использовать nm
на нем. (это не должно быть возможно как ld
не будет связываться с дубликатами, но перейдите в динамические библиотеки и найдите _main
есть)
nm a.out | grep -5 _main
это должно дать 5 строк до и после _main
найдено в двоичном a.out
если у вас есть несколько, см. окружающие символы для подсказок, в каких частях они находятся...
следующий шаг может быть сделать то же самое на каждом динамический lib, который используется. Для получения списка используемых динамических библиотек используйте
otool
otool -L a.out
Я не уверен, как найти другой, но вы можете указать свою собственную точку входа явно и сделать другой неиспользуемой. Вы можете использовать GNU linker ld - e возможность установить точку входа.
-e запись
--entry=запись
использовать запись в качестве явного символа для начала выполнения программа, а не точка входа по умолчанию. Если нет sym- бол с именем entry, компоновщик попытается разобрать запись как число, и используйте это как адрес записи (номер будет интерпретироваться в базе 10; вы можете использовать ведущий 0x для базы 16 или ведущий 0 на основание 8).
для будущих читателей, если у вас есть эта проблема в Windows. Эквивалентный параметр компоновщика -/запись.
вы пытались запустить исполняемый файл через nm
? Это может дать вам некоторые подсказки. Я бы не подумал, что можно связать программу с более чем одной глобально видимой функцией с именем main()
Не уверен, как это успевает случиться.
просмотрите файлы заголовков, которые вы включаете, и посмотрите, нет ли определения, которое переназначает main
к чему-то еще. Это старый трюк, чтобы гарантировать, что основная функция библиотеки вызывается сначала, чтобы сделать некоторую настройку. Как правило, он в конечном итоге вызовет вашу основную функцию, ссылаясь на переопределенное значение.
быстрый Хак:
readelf -s -w my_bin_file > temp.txt
открыть temp.txt, поиск main (с функцией FUNC в одном столбце) Поднимитесь, пока не найдете первый столбец файла-это файл со ссылкой main.
edit: это работает только на GNU Unix вкусов и друзей. OS X использует формат Mach-O, а не ELF.
Я знаю, что в C вы можете иметь другую точку входа, вызываемую перед основной функцией, это может быть идея. Код обычно выглядит так :
void __attribute__ ((constructor)) my_main(void);
возможно, вы можете найти что-то подобное в своем коде.
В C также существуют различные способы поймать основную функцию и вызвать ее после" реальной " основной. Некоторые библиотеки потоков имеют такие хаки, чтобы "подготовить" среду, планировщик и тому подобное.
Это не действительно полезно, но это может объяснить, почему ваш main не вызывается вообще.
надеюсь, что это помогает!
еще одно замечание.
WxWidgets также определяют свои собственные main
С здесь
Как и во всех программах должна быть "основная функция". Под wxWidgets main реализован этот макрос, который создает экземпляр приложения и запускает программу.
IMPLEMENT_APP(MyApp)
похоже, у вас может быть файл с именем b44ExpLogTable.cpp
скомпилирован в вашу двоичную или некоторую библиотеку thirdpart. Похоже, что эта небольшая программа должна генерировать таблицу exp (), но каким-то образом импортируется в ваш проект (ы)
посмотреть этой и в источники FreeImage
создать файл карте. Большинство программ на самом деле не начинаются с main. Mapfile из GCC должен сообщить вам адрес __start или __executable_start, который вы должны иметь возможность взломать и пройти, чтобы увидеть, что вызывает выход вашей программы.