Finding unused (aka "dead") code in Delphi
Asked Answered
R

8

13

Are there any tools that can determine if a function/procedure/method/entire class is used?

I've seen tools that can help a knowledgeable developer track down unused fragments of code (most are for languages other than Delphi) but most have a steep learning curve and/or require considerable digging to determine if a code fragment is used or not.

Delphi's smart linker purportedly does this to reduce the size of the final executable. Unfortunately what little information is given on the smart linker doesn't indicate a way to retrieve what was culled from the hurd.

Admittedly, even if it is possible to find out what the smart linker is eliminating it may be very conservative with its culling.

Robins answered 19/11, 2010 at 16:18 Comment(0)
B
5

Although clumsy and not global, you can examine the source code for the dots in the margin, as shown below. These are lines on which you can set breakpoints because the code hasn't been deadcode eliminated.

This happens, I believe, at the procedure level. I don't know a way to determine this at a less coarse level.

alt text

Bargeman answered 19/11, 2010 at 16:29 Comment(2)
Clumsy indeed. This would require visually scanning each and every source file for missing dots. Although, after testing a few compiler options it appears this feature is available whether debug information is turned on or off. I wonder if this information is extracted by the IDE from the dcus?Robins
Clumsy, yet very useful when trying to understand or refactor large units.Krause
A
4

This thread discusses removing unused units, and talks about tools like Icarus Pascal Analyzer. That tool will do all you need and more. How to "automatically" remove unused units from uses clause?

Admissible answered 19/11, 2010 at 16:51 Comment(2)
Just used that 2 days ago and peeled a way a thick layer of crap from my code.Sammer
Yes, its Code Reduction and Uses reports are pretty helpful but it doesn't have a report that lists functions that are never called or classes that are declared but never used.Robins
A
2

You can use a Code Coverage tool to find unused code. Just run the application and execute all parts manually. The code coverage report will show which parts have not been touched. (Running the tool on the unit tests is not helpful because unused code still can have unit tests).

A free (open source) Code Coverage Tool for Delphi is available here. After running it, check for red lines in the reports, these are the lines which have not been reached.

Delphi Code Coverage is a simple Code Coverage tool for Delphi that creates code coverage reports based on detailed MAP files.

For each unit there will be a unit.html with a summary of the coverage, followed by the source marked up. Green lines were covered. Red lines were not covered lines. The other lines didn't have code generated for it. There is also a CodeCoverage_summary.html file that summarizes the coverage and has links to the generated unit reports.

Maybe the author can add a 'search for dead code' feature in a future version.

Attenuation answered 19/11, 2010 at 18:53 Comment(2)
Good approach, but it's hard to fully excercise many large/mature/spaghetti/legacy/crappy apps, such as those typically found on maintenance projects (which are usually the ones suspected of having dead code). Of course, an A..Z fully automated regression test would be helpful. You know, the kind that simulates datasets and records with every combination of weird properties, simulating year-end, quarter close, leap-year, solar eclipse, holiday processing, run as (application level) admin, regular user, guest, run as (OS) admin, regular user, power user, limited account. XP, 95, Vista, 7...Admissible
continued... And then there's all the things that I, as the developer, have NO IDEA is even in the program. Sounds crazy, if you haven't been there. +1, despite my rant... ;-)Admissible
C
2

You could also check the most commonly used commercial profiler/coverage tool, AQTime from http://www.automatedqa.com

Here's a video on features: http://www.automatedqa.com/products/aqtime/screencasts/coverage-profiling/

Crinoline answered 19/11, 2010 at 19:4 Comment(0)
E
1

In the past I've compiled sources with Free Pascal using the "generate assembler" functionality, and then made some simple filter programs that operate on the source. (for this bit is useful to know that smartlinking is done using linker "section" granularity)

It sometimes gives you insights why certain things are not smartlinked out (e.g. because there is a reference in some table that might be accessed by something in an initialization)

Of course Delphi is not FPC, but when you have hints what to look for, it is a matter of looking at the dots in the margin after a Delphi compile to see if it is smartlinked or not. Likewise, if you have wonder why certain code has (not) been smartlinked out, analyzing a small example program compiled to assembler with FPC can make the reason obvious. (e.g. you find RTTI tables with a reference to it)

The FPC route allows for a systematic route to search the WHY? something is eliminated or not, while map file and code coverage only tells you it is or is not linked in, not why.

For a short description of smart linking see Delphi: Which are the downsides of having unused units listed in the uses clause?

Elisabetta answered 19/11, 2010 at 20:0 Comment(0)
C
0

Checkout the tools at http://www.peganza.com/ to help with some of your tasks.

Icarus is freeware and it analyzes your 'uses' clauses to allow you to remove unused references.

Pascal Analyzer is the full version which includes Icarus functionality and a ton of other tools.

Crinoline answered 19/11, 2010 at 17:52 Comment(1)
Ooops...don't know how I missed it! Good luck regardless!Crinoline
R
0

Maybe CodeHealer could help you with unused code

CodeHealer performs an in-depth analysis of source code, looking for problems in the following areas:

Audits: Quality control rules such as unused or unreachable code, use of Delphi directive names and keywords as identifiers, identifiers hiding others of the same name at a higher scope, and more. Checks: Potential errors such as uninitialised or unreferenced identifiers, dangerous type casting, automatic type conversions, undefined function return values, unused assigned values, and more. Metrics: Quantification of code properties such as cyclomatic complexity, coupling between objects (Data Abstraction Coupling), comment ratio, number of classes, lines of code, and more.

Result answered 19/11, 2010 at 18:26 Comment(0)
M
0

For units, use Pascal Analyzer. You might need to use it a multiple of times.

For objects/classes that are registered in class factories (and the like), you will need to double check manually, as they will be fully compiled in. The reason for this is that the compiler doesn't know if you actually use them or not.

For methods, you need to check for the blue dots. Not very practical, so there is another way (from what I have been told when I investigate the same topic). You need to do a full build with a detailed map file enabled. Once that is done, you need to compare the source to see if there is an entry in the map file. If not, then the code is not compiled in - possibly dead code (possibly because if it is component, then it might be that you don't use that functionality).

Mayfly answered 19/11, 2010 at 19:54 Comment(1)
Using the map file is an interesting idea. If I could find a way to generate a list of all methods and first class subroutines in a code base, extract the list of segments from the Publics by Name section in the map file and compare the two I could create a list of which were excluded by the linker.Robins

© 2022 - 2024 — McMap. All rights reserved.