2

我有一个c包含多个文件的巨大(夸张)程序的源代码。我希望是否有任何方法可以找到程序中使用(声明和调用)的所有函数(标准和内置)。我知道我可以通过首先将输出重定向到文件然后使用来选择函数调用来编译它function并使用and之system calls类的工具对其进行编译和跟踪。或者我可以在所有文件的 shell 上使用正则表达式,但我还不知道正则表达式。那么有没有人知道一种工具可以帮助我快速找到ac程序中调用和声明的所有函数?ltracestracegrep

4

3 回答 3

3

检查这是否有帮助,代码中的注释:

#!/bin/bash

# For each .c in the current path (recursive)
for f in $(find . -name '*.c'); do
    # Extract the functions and his location with aux-info
    # Send the results to output.info
    # Send errors to /dev/null
    gcc -aux-info output.info $f 2>/dev/null
    # Extract function names from output.info excluding std headers and comments
    grep -Ev "/usr|compiled from" output.info
done
# Remove output.info
rm output.info

由于您似乎正在尝试按照模式提取自己的代码:type function(params),您可以避免使用gcc -aux-info,请尝试以下操作:

#!/bin/bash

# For each .c in the current path (recursive)
for f in $(find . -name '*.c'); do
    # Extract the lines starting with a letter or underscore
    #                 and ending with ')' or '{' or '}' ignoring trailing spaces
    grep --with-filename --line-number --color '^[a-z|A-Z|_].*[)|{|} ]$' $f
done

另一种结合readelfand的方式awk,注意在这种情况下,您需要提供程序/二进制文件的名称而不是源文件:

# Column 3 != 0 and Column 4 = "FUNC" and Column 8 not starting with _
readelf -sW your_program | awk '$3 != 0 && $4 == "FUNC" && $8 !~ /^ ?_/ {print $8}'
于 2020-11-26T14:57:53.343 回答
1

因为函数指针,不,没有。考虑这个程序:

#include <dlfcn.h>

int main(int argc, char **argv) {
    void *handle = dlopen(argv[1], RTLD_LAZY);
    void (*f)(void) = dlsym(handle, argv[2]);
    f();
    dlclose(handle);
}

很明显,您不可能希望列出它可以调用的所有函数。

于 2020-11-26T15:33:10.410 回答
1

@David,给了我一个很好的答案,但是在学习之后for loopsbash我想出了一种就消息而言更简洁的方法。这种方法最好的一点是它会扫描文件statically,这意味着即使某些函数被分配给@joseph 指出的指针,您也将能够看到所有函数的列表calls。这个程序的输出并不像它可能的那样干净,因为我不太了解正则表达式,所以如果有人知道更好的方法,不要忘记清理它,

#!/bin/bash

#go through each .c file in the directory
for f in $(find . -maxdepth 1 -name "*.c");do
    #print the name of the file
    echo "$f"
    #print the content of the file
    #and then choose the lines that contain function calls
    cat -n $f|grep -v "if\|else\|for\|while\|return"| grep --color=always "_*(\|[[:alpha:]]*("

done
于 2020-11-26T20:48:24.410 回答