繁体   English   中英

如何找到我的程序的 main(...) function?

[英]How do I find my program's main(…) function?

我目前正在将一个包含数百个代码文件和依赖项的项目移植到几个第三方库到 Mac Os 上。 我终于达到了程序编译没有警告或错误的地步,但它似乎没有执行我自己的主要 function。

相反,它似乎执行了其他一些似乎属于第三方的主要 function。 这个 function 将一些诊断数据写入控制台,然后退出:

(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.

我无法使用调试器找出这个主要的 function 所在的位置,因为虽然堆栈跟踪似乎有效,但 gdb 没有向我显示每个堆栈条目的正确行号和文件名(有关详细信息,请参阅这个未解决的问题)。

搜索需要几分钟才能完成,但没有返回任何结果。

我的项目在其他库中使用 SDL,但我获得了 SDL_Main() 和潜在问题的奖励,并且在完美运行的 SDL 项目模板之上构建了我的项目。 所以我很确定我自己的主要 function 是有效的。

你知道可能出了什么问题吗? 我目前不知道如何找到和删除流氓主 function。

谢谢,

阿德里安

编辑:正如我刚刚发现的那样,我在使用字符串“这是自动生成的”搜索文件文件时犯了一个错误。 我刚刚发现了几十个具有相同字符串的文件,它们都属于我正在使用的第三方库之一 FreeImage。 因此,问题似乎与 FreeImage 有关,但我仍然不确定如何继续,因为我已将 Freeimage 编译为包含 MacOs makefile 的库并且仅包含该库。 我会尝试重建一个更新版本的 FreeImage 并查看它是否解决了我的问题。

它可能是在调用 main() 之前失败的 static object 的初始化程序吗?

你有几个主要的二进制文件吗? 尝试在其上使用nm (这应该是不可能的,因为ld不会与重复项链接,但 go 进入动态库并在那里查找_main

nm a.out | grep -5 _main

这应该在二进制a.out中找到的任何_main之前和之后给出 5 行

如果您有多个,请查看周围的符号以提示它们位于哪些部分...

下一步可以对使用的每个动态库执行相同的操作。 要获取使用的动态库的列表,请使用otool

otool -L a.out

我不确定如何找到另一个,但您可以明确指定自己的入口点并使另一个不使用。 您可以使用 GNU linker ld -e 选项来设置您的入口点。

-e 条目

--entry=条目

使用入口作为开始执行程序的显式符号,而不是默认入口点。 如果没有名为 entry 的符号,linker 将尝试将 entry 解析为一个数字,并将其用作入口地址(该数字将以 10 为基数解释;您可以使用前导 0x 表示基数 16,或者以 8 为基数的前导 0)。

对于未来的读者,如果您在 Windows 中遇到此问题。 等效的 linker 选项是/ENTRY

您是否尝试通过nm运行您的可执行文件? 或许能给你一些提示。 我认为不可能将一个程序与多个全局可见的 function 命名为main()链接,不确定这是如何发生的。

查看您包含的 header 文件,看看是否没有将main重新映射到其他内容的定义。 这是确保首先调用库的主要 function 进行一些设置的老技巧。 一般来说,它最终会通过引用重新定义的值来调用你的主function。

快速破解:

readelf -s -w my_bin_file > temp.txt

打开 temp.txt,搜索 main(在一列中带有 FUNC)Go 直到找到第一个 FILE 列 - 这是带有链接 main 的文件。

编辑:这仅适用于 GNU Unix 风格和朋友。 OS X 使用 Mach-O 格式,而不是 ELF。

我知道在 C 中,您可以在主 function 之前调用不同的入口点,这可能是一个想法。 代码通常如下所示:

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

也许您可以在代码中搜索类似的内容。

在 C 中,也有不同的方法来捕捉主 function 并在“真正的”主之后调用它。 一些线程库为了“准备”环境、调度程序和类似的东西而进行了这种黑客攻击。

这并不是很有用,但这可以解释为什么你的 main 根本没有被调用。

希望这可以帮助!

另一个注意事项。

WxWidgets 也定义了自己的main

这里

与所有程序一样,必须有一个“主”function。 在 wxWidgets 下 main 是使用这个宏实现的,它创建一个应用程序实例并启动程序。

IMPLEMENT_APP(MyApp)

看起来您可以将一个名为b44ExpLogTable.cpp的文件编译到您的二进制文件或某个第三方库中。 看起来那个小程序是生成一个 exp() 表,但不知何故被导入到您的项目中

FreeImage 资源中查看这个和这个

生成 map 文件。 大多数程序实际上并不是从 main 开始的。 来自 GCC 的映射文件应该告诉您 __start 或 __executable_start 的地址,您应该能够闯入并逐步查看导致程序退出的原因。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM