DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Why We Still Struggle With Manual Test Execution in 2025
  • Copy SQL Execution Plan from One Database to Another in Oracle 19c
  • Level Up Your Code With Formal Methods
  • Ulyp: Recording Java Execution Flow for Faster Debugging

Trending

  • Why Database Migrations Take Months and How to Speed Them Up
  • How Can Developers Drive Innovation by Combining IoT and AI?
  • Comprehensive Guide to Property-Based Testing in Go: Principles and Implementation
  • How To Build Resilient Microservices Using Circuit Breakers and Retries: A Developer’s Guide To Surviving

Debugging Step by Step - Active and Passive Debugging

By 
Istvan Forgacs user avatar
Istvan Forgacs
·
Sep. 09, 14 · Interview
Likes (0)
Comment
Save
Tweet
Share
7.4K Views

Join the DZone community and get the full member experience.

Join For Free

The main goal of debugging is to find bugs. The most important question is how? The entry criterion of bug hunting is obviously the knowledge of your code. If you don’t understand the code in an appropriate level you will find the fault with difficulties and your code fix will results in newer bugs, while the code becomes worse. Assume that your code understanding is sufficient for debugging. What to do next?

Most of the program executions resulting in a failure have a long trace containing lots of execution steps. Checking all of them is almost impossible and it would take too long. We need methods which reduces the number of execution steps to consider. The methods reducing the executions to be investigated are called active debugging. 

On the contrary, debugging methods which leave all the execution steps to be visited are called passive debugging. What do these debuggers do? They display or log the available data of the inner state of an execution step.  Traditional debuggers and loggers fall into this category.It seems, something is wrong with this argument since you can insert breakpoints at any place and skip most of the execution steps. However, inserting breakpoints can only be possible if you apply an active method.

Known active debugging techniques

During debugging you always make hypotheses. These can be positive and negative. A negative hypothesis is when you exclude some parts of the executed code as being faulty. If you assume, then a method cannot be a source of the failure you can step over it. That’s why code understanding is so important.

A positive hypothesis is on the contrary an assumption what can be wrong. If you have a clear hypotheses, you can concentrate on those part of the code which support or falsify your hypothesis. If the hypothesis is good you can narrow it, if it’s wrong you have to change it. For example, you can guess that the cause of a sorting problem is the erroneous handling of hyphens in family names. 

Active debugging based on hypotheses cannot be automated. You have to use your brain. There are other methods, however, which can be automated. The first one is input reduction, also called as delta debugging, see https://dzone.com/articles/debugging-step-step-delta. This is the first step of bug hunting after understanding the code. Here is an example.

Consider a list of 100 employees in alphabetic order, and assume the order is false. What to do? We can use a traditional debugger and try to find the fault. However it’s a completely wrong solution. Firstly, we should reduce the input, i.e. the number of employees. Starting from the wrong ordering we observed in the list, we can construct a test that fails as well, with only quite a few names.

What did happen? We have a new execution trace with much less execution steps. This is clearly active debugging. By applying the method input is minimized so that the result of the execution be correct for any smaller input, but faulty for the selected one. The method can be automated, or you can do this work manually depending on the actual case.

Comparison debugging

Another active debugging method introduced by our Jidebug team is comparison debugging.

Assume we have a bug, i.e. a test execution failed. If we have another, but bug free execution we can use it as standard. Actually, if the inputs of the two executions are the same or similar so that the two executions should cover the same execution path, the difference  is a good starting point of bug hunting, and analyzing the differences you either will find the fault or you can make a good hypothesis. For example, if the execution passes for loading a small image, but fails for a larger one, the first can be used as a standard. There should be some differences in the execution trace or the two executions should behave identically. The method can primarily be used for non-reproducible bugs when the test fails at the tester, but works well at the developer’s environment.

To learn more please wait for our subsequent article coming soon. If you cannot wait, you can jump to our home page http://jidebug.com, or try our tool based on comparison debugging.

Influence debugging

Considering yet another active debugging technique, here is a short introduction of influence debugging.   

Assume you detect a failure during a program execution (or which is the same, a test case). Using a traditional debugger you should analyze quite a lot statements superfluously. Why? Because about 90% of the code has no influence on the failure. If so, why we don’t omit them? Yes, this is the solution: let’s filter out all the code/statements which have no influence on the failure. Therefore, an appropriate tool (Jidebug) can collect all the influences and arrange them as influence chains. If you go back along these chains you may find the defect so that no superfluous statements are traced. This is obviously an active debugging method, which can be used for many cases, even if for missing case errors (when some code is missing).

We are planning a detailed article about influence debugging, but anxious reader can go to the Jidebug page above.

Efficient debugging applies active methods

Active debuggers can be used together. For example, after reducing the input (delta debugging), you can use comparison debugging. Starting from a selected execution difference you can apply both influence debugging and hypothesis to find the bug finally.

Passive and active debugging complete each other, thus you should use them together. However, to reduce debugging time you have to cut execution points to be visited as much as possible.  This can be done only by applying active debugging methods. That’s why active debugging is so important. 

Execution (computing)

Opinions expressed by DZone contributors are their own.

Related

  • Why We Still Struggle With Manual Test Execution in 2025
  • Copy SQL Execution Plan from One Database to Another in Oracle 19c
  • Level Up Your Code With Formal Methods
  • Ulyp: Recording Java Execution Flow for Faster Debugging

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!