Как мне найти основную (...) функцию моей программы? - PullRequest
7 голосов
/ 05 марта 2009

В настоящее время я портирую проект с несколькими сотнями файлов кода и зависимостей на несколько сторонних библиотек на 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. Поэтому я совершенно уверен, что моя собственная функция main действительна.

У вас есть идеи, что может пойти не так? В настоящее время у меня нет идей, как найти и удалить основную функцию мошенника.

Спасибо

Адриан

РЕДАКТИРОВАТЬ: Как я только что узнал, я сделал ошибку при поиске файлов со строкой «Это автоматически сгенерировано». Я только что нашел несколько дюжин файлов с одинаковой строкой, все принадлежащие FreeImage, одной из сторонних библиотек, которые я использую. Итак, проблема, похоже, связана с FreeImage, но я до сих пор не уверен, что делать дальше, так как я скомпилировал Freeimage как библиотеку с приложенным make-файлом MacOs и включил только библиотеку. Я постараюсь пересобрать более новую версию FreeImage и посмотреть, исправит ли это мою проблему.

Ответы [ 10 ]

8 голосов
/ 05 марта 2009

Может ли это быть инициализатор статического объекта, который завершается сбоем до вызова main ()?

3 голосов
/ 05 марта 2009

У вас есть несколько основных в двоичном? Попробуйте использовать nm на нем. (это не может быть возможно, так как ld не будет связываться с дубликатами, но зайдите в динамические библиотеки и поищите там _main)

nm a.out | grep -5 _main

Это должно дать 5 строк до и после любого _main, найденного в двоичном файле a.out

Если у вас их несколько, см. Окружающие символы для подсказок, в каких частях они находятся ...

Следующим шагом может быть то же самое для каждой используемой динамической библиотеки. Для получения списка используемых динамических библиотек используйте otool

otool -L a.out
2 голосов
/ 05 марта 2009

Я не уверен, как найти другую, но вы можете явно указать свою собственную точку входа и сделать другую неиспользуемой. Вы можете использовать GNU linker ld -e, чтобы установить точку входа.

-е запись

- запись = запись

Используйте запись в качестве явного символа для начала выполнения вашего программа, а не точка входа по умолчанию. Если нет Бол, названный entry, компоновщик попытается проанализировать запись как число, и использовать это как адрес входа (число будет интерпретировано в базе 10; Вы можете использовать ведущий 0x для базы 16 или ведущий 0 для базы 8).

Для будущих читателей, если у вас есть эта проблема в Windows. Эквивалентная опция компоновщика: / ENTRY .

1 голос
/ 05 марта 2009

Быстрый взлом:

readelf -s -w my_bin_file > temp.txt

Открыть файл temp.txt, найти основной (с FUNC в одном столбце) Идите вверх, пока не найдете первый столбец FILE - это файл со связанной основной.

edit: Это работает только с версиями GNU Unix и друзьями. OS X использует формат Mach-O, а не ELF.

1 голос
/ 05 марта 2009

Просмотрите файлы заголовков, которые вы включили, и посмотрите, нет ли определения, которое переназначает main на что-то другое. Это старый трюк, чтобы гарантировать, что главная функция библиотеки вызывается первой, чтобы выполнить настройку. Как правило, он в конечном итоге вызывает вашу основную функцию, ссылаясь на переопределенное значение.

1 голос
/ 05 марта 2009

Вы пробовали запустить свой исполняемый файл через nm? Это может дать вам несколько советов. Я не думаю, что было бы возможно связать программу с более чем одной глобально видимой функцией с именем main(), не знаю, как это удастся.

0 голосов
/ 06 марта 2009

Создать файл карты. Большинство программ на самом деле не запускаются в основном. Картографический файл из GCC должен указывать вам адрес __start или __executable_start, который вы должны быть в состоянии взломать и пройти через него, чтобы увидеть, что вызывает выход вашей программы.

0 голосов
/ 06 марта 2009

Похоже, вы можете иметь файл с именем b44ExpLogTable.cpp, скомпилированный в ваш двоичный файл или какую-то третью библиотеку. Похоже, что эта маленькая программа предназначена для генерации таблицы exp (), но каким-то образом ее импортировали в ваш проект (ы)

См. это и это в FreeImage sources

0 голосов
/ 05 марта 2009

Другое примечание.

WxWidgets также определяют свои собственные main

С здесь

Как и во всех программах, должна быть «основная» функция. Под wxWidgets main реализован с помощью этого макроса, который создает экземпляр приложения и запускает программу.

IMPLEMENT_APP(MyApp)

0 голосов
/ 05 марта 2009

Я знаю, что в C у вас может быть другая точка входа, вызываемая перед основной функцией, это может быть идеей. Код обычно выглядит так:

void __attribute__ ((constructor)) my_main(void);

Может быть, вы можете найти что-то подобное в вашем коде.

В C также есть различные способы перехватить основную функцию и вызвать ее после «реального» main. Некоторые библиотеки потоков имеют такие хаки, чтобы «подготовить» окружение, планировщик и тому подобное.

Это не совсем полезно, но это может объяснить, почему ваш main вообще не вызывается.

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...