我们正在寻找一个程序,通过该程序,我们可以轻松列出所有编译在一起的文件以生成可执行文件。
用例:假设,我们有大型存储库,我们想知道存储库中存在的文件是什么,这些文件被编译为可执行文件(即a.out)
例如:
class ORDER
{
// order properties
private $_db = null;
private $_settings = null;
private $_user = null;
private $_userLevel = 1;
...
/**
* Order Constructor
* @param $db
* @param $settings
* @param $user
* @param $need_db_record
* @return ORDER
*/
public function __construct(&$db, &$settings, &$user, $need_db_record=false, $check_user_change = true)
{
$this->_db = $db;
$this->_settings = $settings;
$this->_user = $user;
...
}
/**
* Returns class instance
* @return USER
*/
public function user()
{
return $this->_user;
}
但它没有列出所有头文件。 请建议。
答案 0 :(得分:3)
如何使用可用的调试符号从可执行文件中提取源代码?
你不能那样做。我猜你是在Linux / x86-64上(你的问题是operating system和ABI具体,具体是调试格式)。当然,您应该pass -g
(或even -g3
)执行可执行文件的所有gcc
编译命令。如果没有使用-g
或-g3
选项来编译每个 translation unit(包括共享库的那些!),您可能没有足够的信息。
即使debug information格式为DWARF,ELF可执行文件也不包含源代码,但只有引用源代码(例如源文件路径,位置为行号和列号)。因此,调试信息包含文件src/foo.c
,第34行第5列等内容(但不要提供有关该位置附近src/foo.c
的内容的内容)。当然,一旦gdb
知道文件路径src/foo.c
,它就能够读取该源文件(如果可用并且最新的w.r.t.可执行文件),以便它可以列出它。
提取调试元数据是一个不同的问题。理解DWARF后,您可以使用objdump
或readelf
或addr2line
或dwarfdump or libdwarf等工具;你也可以编写脚本gdb
(GDB的最新版本可能是extendable在Python或Guile中)并在你的ELF可执行文件中使用它。
也许你应该考虑伊恩·泰勒的libbacktrace。它使用DWARF信息在运行时提供漂亮的回溯。
BTW,cgdb
(仅ddd
)只有前端到gdb
,它完成了处理DWARF信息的所有实际工作。它是free software,你可以研究它的源代码。
我只有
a.out
然后我想列出完成的文件名
您可以尝试使用dwarfdump -i | grep DW_AT_decl_file
,但可以使用GNU awk
命令代替grep
。您需要深入了解details of DWARF specifications,并且需要了解有关elf(5)格式的更多信息。
它没有列出所有头文件
这是预期的。大多数标头文件不包含任何代码,只有声明(例如printf
未在<{1}中实现 但是在C standard library的某个C源文件中,例如在tree/src/stdio/printf.c
中,如果您使用musl-libc;它只是在<stdio.h>
中声明。 DWARF(和其他调试信息格式)正在描述binary code。并且包含一些头文件只是为了访问一些预处理器宏(在预处理时间会扩展或跳过)。
也许你梦见homoiconic编程语言,然后尝试使用Common Lisp(例如SBCL)。
如果您的问题是如何使用/usr/include/stdio.h
,请阅读Debugging with GDB手册。
如果您的问题是关于decompilers,请注意这是一项不可能的任务(例如,因为Rice's theorem)。顺便说一下,大多数Linux发行版中的程序通常都是free software,所以很容易获得源代码(你甚至可以避免在Linux上使用专有软件)。
顺便说一句,您也可以通过将more flags传递给gdb
,在编译时间做更多事情。您可以pass gcc
或-H
(等等)到-M
(除gcc
之外)。您甚至可以考虑编写自己的GCC plugin来收集某些数据库中所需的信息(但这可能不值得付出努力)。您还可以考虑改进build automation(例如,在Makefile
中添加更多内容)以收集此类信息。顺便说一下,许多大型C程序使用一些metaprogramming技术,通过工具(例如#line
directives)或脚本生成一些-g
个文件,这些文件可能包含bison 生成的 ,那么你想保留什么样的文件路径??
我们正在寻找一个程序,通过该程序,我们可以轻松列出所有编译在一起的文件以生成可执行文件。
如果您正在编写该可执行文件并从其源代码编译它,我建议您在构建时收集该信息。将某些.c
和/或-M
标记传递给-H
可能同样重要,可能会传递到某些生成的 gcc
文件中(请参阅{{ 3}}获取灵感;但您的timestamp.c
可能包含timestamp.c
等提供的信息。您的时间戳文件可能包含this版本控制元数据(如git
中生成的)。另请阅读this Makefile
和reproducible builds。