10

I was looking for a way of finding statically unreachable functions in a (very) big C++ project. I had tried using doxygen and other static analysis tools suggested here but it seemed that the project is too complicated for them to handle. Finally i decided that using GCC tools (g++, gprof, gcov, etc.) is the safest option, although I couldn't figure out how to do it.

I think the g++ optimizations eliminate statically unreachable functions but I'm not sure how to get the names of the functions it eliminates.

Do you have any suggestions?

peterh
  • 11,875
  • 18
  • 85
  • 108
stnr
  • 435
  • 4
  • 14

2 Answers2

8

Dead code optimization is typically done by the linker - the compiler doesn't have the overview. However, the compiler might have eliminated unused static functions (as they have internal linkage).

Therefore, you shouldn't be looking at GCC options, but at ld options. It seems you want --print-gc-sections. However, note that you probably want GCC to put each function in its own section, -ffunction-sections. By default GCC will put all functions in the same section, and ld isn't smart enough to eliminate unused functions - it can only eliminate unused sections.

MSalters
  • 173,980
  • 10
  • 155
  • 350
  • The `--print-gc-sections` option prints result like this: `Removing unused section '.text._DriverUnloadHandler' in file '/tmp/ccLoxO8q.ltrans0.ltrans.o'`. So how to find the original C file name? – smwikipedia Aug 17 '18 at 09:03
  • And the `-ffunction-sections` doesn't work with assembly code since no compilation is involved. So all functions in assembly code will be in the `.text` section, which renders the `--print-gc-sections` less useful to detect unused functions. – smwikipedia Aug 17 '18 at 09:14
  • @smwikipedia: Check `objdump -W /tmp/ccLoxO8q.ltrans0.ltrans.o` – MSalters Aug 17 '18 at 09:15
  • 1
    @smwikipedia: As for assembly, it can be structured in ways which are not expressible as functions. For instance, you cannot call into the middle of a C function; C functions have a single entry point. Assembly is just a sequence of instructiosn, and you can jump to any point in that sequence. In x86, rhere's not even a restriction that you jump to an actual instruction boundary ! – MSalters Aug 17 '18 at 09:18
  • Yes. I agree with you. So these options are kind of useful to C only. But that's good enough for most scenarios. Thanks. – smwikipedia Aug 17 '18 at 09:19
  • 1
    @smwikipedia: Well, you can of course use `.segment .text.MyAssemblyFoo` to manually create sections in your assembly. That's the double-edged nature of assembly: you can do everything manually, and you must do everythign manually. – MSalters Aug 17 '18 at 09:22
-1

gcov is what you're looking for. You have that listed in the question, have you not looked at it?

Andrew Sledge
  • 10,163
  • 2
  • 29
  • 30
  • 5
    Not really, "gcov creates a logfile called sourcefile.gcov which indicates how many times each line of a source file sourcefile.c has executed." This is dynamic analysis not static. – stnr Nov 16 '10 at 15:54