有没有办法找到一个c程序中使用的所有函数?

Is there a way to find all the functions used in a c program?

我有一个包含多个文件的巨大(夸大)c 程序的源代码。我希望是否有任何方法可以找到程序中使用(声明和调用)的所有函数(标准函数和内置函数)。我知道我可以编译它并使用 ltracestrace 等工具跟踪 functionsystem calls,方法是先将输出重定向到一个文件,然后使用 grep 到 select 函数调用。或者我可以在所有文件的 shell 上使用正则表达式,但我不知道正则表达式(还)。那么有谁知道有什么工具可以帮助我快速找到c程序中调用和声明的所有函数吗?

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

#!/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

另一种组合 readelfawk 的方法,请注意,在这种情况下,您需要提供 program/binary 的名称而不是源文件:

# Column 3 != 0 and Column 4 = "FUNC" and Column 8 not starting with _
readelf -sW your_program | awk ' != 0 &&  == "FUNC" &&  !~ /^ ?_/ {print }'

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

#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);
}

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

@David,给了我一个很好的答案,但是在学习 for loops 中的 bash 之后,我想出了一个就消息而言更简洁的方法。这种方法最好的一点是它扫描文件 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