cfunctionsystem-callsltrace

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


I have the source code for a huge (exaggerated) c program with multiple files. I was hoping if there was any way to find all the functions (both standard and builtin) used (both declared and called) in the program. I know I can compile it and track the function and system calls using tools like ltrace and strace, by redirecting the output to a file first and then using grep to select the function calls. Or I can use regex on shell on all the files, but I don't know regex (yet). So does any one know a tool that could help me to quickly find all the functions called and declared in a c program?


Solution

  • Check if this helps, comments in code:

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

    Since it seems that you are trying to extract your own code following a pattern: type function(params), you can avoid using gcc -aux-info, try the following:

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

    Another way combining readelf and awk, notice that in this case you need to provide the name of the program/binary instead of the source files:

    # 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}'