15

I was wondering what are some techniques to locate which code implemented a specific feature, on a desktop application.

I am a junior developer, with only professional programming experience lying around web programming. In the Web it is easier to do that. For example, you "inspect" a button with the browser tools, and you can see what is being done when you click it. And then, presuming you have the full source code, you can drill down the hierarchy of the calls.

But how do you do this in desktop applications? At least, without having to dive into the full codebase?

8
  • 7
    Instead of reading through the code, you can sometimes use a debugger. How that works (and how user-friendly that is for you) depends on the language, debugger, and debugger interface used. In any case, using a debugger is an art to be learnt – but once it's learnt it's a very powerful tool. I should learn to use one myself some time.
    – amon
    Mar 8, 2014 at 22:56
  • And where should I set up the breakpoints?
    – py_script
    Mar 8, 2014 at 23:14
  • The setup of the breakpoint depends entirely upon your application and how it is organized.
    – user40980
    Mar 8, 2014 at 23:51
  • 2
    It can actually be somewhat hard to "inspect" and see where and how web-interfaces were made, with new object-oriented systems like Backbone.js and templates, which are becoming more popular.
    – NoBugs
    Mar 9, 2014 at 3:16
  • 1
    @jeffo When you do, for example, File->Open in an application(lets say LibreOffice's Writer) how can you find what is the call sequence behind that?
    – py_script
    Mar 9, 2014 at 21:31

3 Answers 3

22

Back Tracing

Back tracing is locating an endpoint to an event associated with the feature (see below). Once there, a breakpoint is placed in the debugger. The feature is triggered and when the debugger stops. The call stack is reviewed to back trace the calling path. While walking up the call stack you can take notes on variable states, or place new breakpoints to inspect the event again.

The feature is trigger again and the debugger stops at the new breakpoints. You can then repeat back tracing or perform forward tracing until the goal is found.

Pros & Cons

  • It's always easier to walk up the call stack and see how you got somewhere.
  • There could be millions of conditions that need to be true before reaching an endpoint. If you know the endpoint already you've saved yourself lots of work.
  • If the feature is broken. You may never reach the endpoint, and time can be wasted trying to figure out why.

Endpoint Discovery

To debug a feature you have to know where in the source code the final goal is achieved. Only from this point can you backtrace to see how the code got there. An example; To understand how undo is performed. You know where in the code things are undone, but you don't know how things get there. This would be a candidate for backtracing to figure out how the feature works.

Forward Tracing

Forward tracing is locating a start point for an event associated with a feature (see below). Once there, logging messages are inserted into the source code or breakpoints are set. This process is repeated as you progress further away from the start point until you discover the goal for the feature.

Pros & Cons

  • It's the easiest starting point for finding a feature.
  • Code complexity reduces the effectiveness of forward tracing. The more conditions there are in the code the greater the chance you'll go in the wrong direction.
  • Forward tracing often results in setting breakpoints that will be triggered by unrelated events. Interrupting the debugging process and interfering with your search.

Start Point Discovery

You can use keywords, user interface identifiers (button IDs, window names) or easy to find event listeners associated with the feature. For example, you might start with the button used to trigger an undo feature.

Process Of Elimination

You can think of this as the middle point compared to start point and end point positions. You perform a process of elimination when you already know a piece of code is used in a feature, but it is neither the start or end of the feature.

The direction you take from the middle point depends upon the number of entries and exits. If the code chunk is used in many places, then back tracing from this position could be very time consuming as they all have to be inspected. You then employ a process of elimination to reduce this list. Alternative, you can perform a forward trace from this point, but again if the code chunk branches out to many places this can also be a problem.

You have to reduce position directions by not following paths that clearly wouldn't be executed for the feature. Moving past this code and only placing breakpoints where it's likely related to the feature.

Middle point debugging often requires more advance IDE features. The ability to see code hierarchy and dependencies. Without those tools it's difficult to do.

Pros & Cons

  • Middle points are often the first peice of code that pops into your head when you think of the feature. You say to yourself "Ah, that has to use XXXX to work."
  • Middle points can reveal start points the easiest.
  • Middle points can be an easy way to pick up the trail to a feature when lost by synchronization or threading changes.
  • Middle points can take you to code you are not familiar with. Costing you time to learn what is going on.
3
  • Thanks Matthew, great approach. But how do you find a startpoint(sorry if it is obvious to all but me)?
    – py_script
    Mar 9, 2014 at 21:35
  • @py_script What programming language are you having trouble with?
    – Reactgular
    Mar 10, 2014 at 13:52
  • It is not about a specific problem I have, but my main Desktop programming language is Java, so lets go with it
    – py_script
    Mar 10, 2014 at 20:35
12

Assuming that the feature is tied to some UI thingie, like a Button or Menu, what I tend to do follows (very tedious but it works). This is looking through the Source Code, not using a debugger.

  1. Search for the (hopefully distinctive) text on the button, e.g. "Super Feature X3".
  2. That is probably in a file with some constant, e.g. SUPER_BUTTON_3 = "Super Feature X3". For future reference, remember this file name.
  3. There may be another layer (of even two) of abstraction, keep searching to get the "real" String that gets used by the Button. Note how this is done for the future.
  4. Now search on that constant. Hopefully you have now found the Button. Maybe that is where they connect the ActionListener. (I'm taking Java-ese here, YMMV, but the concept still holds)
  5. If necessary, search on that Button and you'll eventually find where it gets connected to a Listener.
  6. Perhaps that listener really redirects to other listeners (the "real" functionality) based upon the constant, if so, follow that if/else or case statement. NOTE: If there is a central dispatchy thing, this is a great place to setup breakpoints.
  7. Finally, you should be at the actual code.

As @amon noted, sometimes a Debugger is simpler...

1
  • Interesting one...thankfully such names are usually hardcoded in the code :)
    – py_script
    Mar 9, 2014 at 21:38
4
  • If you can find any related code at all, you can use your source control software to show you the entire commit or nearby commits that added it. That should show you everything that was required to implement that feature.

  • One easy way to find some starting point to look would be to grep through your codebase looking for the text on the button.

  • Often, people will put an issue id from their issue tracker in their commit messages. If you can find an issue describing the feature request, then you can search for commits with that issue id.

1
  • That's a smart approach but I think it works only on corporate environments. What if you have just a tarball?
    – py_script
    Mar 9, 2014 at 21:38

Not the answer you're looking for? Browse other questions tagged or ask your own question.