Как мне найти функцию main(…) моей программы?

StackOverflow https://stackoverflow.com/questions/614492

  •  03-07-2019
  •  | 
  •  

Вопрос

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

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

Спасибо,

Адриан

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

Это было полезно?

Решение

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

Другие советы

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

nm a.out | grep -5 _main

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

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

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

otool -L a.out

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

-e запись

--entry=запись

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

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

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

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

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

readelf -s -w my_bin_file > temp.txt

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

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

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

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

Возможно, вы сможете поискать что-то подобное в своем коде.

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

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

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

Еще одно замечание.

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

От здесь

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

IMPLEMENT_APP(MyApp)

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

Видеть этот и это в Источники бесплатных изображений

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top