Search

3.5 — More debugging tactics

In the previous lesson (3.4 -- Basic debugging tactics), we started exploring how to manually debug problems. In that lesson, we offered some criticisms of using statements to print debug text:

  1. Debug statements clutter your code.
  2. Debug statements clutter the output of your program.
  3. Debug statements require modification of your code to both add and to remove, which can introduce new bugs.
  4. Debug statements must be removed after you’re done with them, which makes them non-reusable.

We can mitigate some of these issues. In this lesson, we’ll explore some basic techniques for doing so.

Conditionalizing your debugging code

Consider the following program that contains some debug statements:

When you’re done with the debugging statement, you’ll either need to remove them, or comment them out. Then if you want them again later, you’ll have to add them back, or uncomment them.

One way to make it easier to disable and enable debugging throughout your program is to make your debugging statements conditional using preprocessor directives:

Now we can enable debugging simply by commenting / uncommenting #define ENABLE_DEBUG. This allows us to reuse previously added debug statements and then just disable them when we’re done with them, rather than having to actually remove them from the code. If this were a multi-file program, the #define ENABLE_DEBUG would go in a header file that’s included into all code files so we can comment / uncomment the #define in a single location and have it propagate to all code files.

This addresses the issue with having to remove debug statements and the risk in doing so, but at the cost of even more code clutter. Another downside of this approach is that if you make a typo (e.g. misspell “DEBUG”) or forget to include the header into a code file, some or all of the debugging for that file may not be enabled. So although this is better than the unconditionalized version, there’s still room to improve.

Using a logger

An alternative approach to conditionalized debugging via the preprocessor is to send your debugging information to a log file. A log file is a file (normally stored on disk) that records events that occur in software. The process of writing information to a log file is called logging. Most applications and operating systems write log files that can be used to help diagnose issues that occur.

Log files have a few advantages. Because the information written to a log file is separated from your program’s output, you can avoid the clutter caused by mingling your normal output and debug output. Log files can also be easily sent to other people for diagnosis -- so if someone using your software has an issue, you can ask them to send you the log file, and it might help give you a clue where the issue is.

While you can write your own code to create log file and send output to them, you’re better off using one of the many existing third-party logging tools available. Which one you use is up to you.

For illustrative purposes, we’ll show what outputting to a logger looks like using the plog logger. Plog is implemented as a set of header files, so it’s easy to include anywhere you need it, and it’s lightweight and easy to use.

Here’s output from the above logger (in the Logfile.txt file):

2018-12-26 20:03:33.295 DEBUG [4752] [main@14] main() called
2018-12-26 20:03:33.296 DEBUG [4752] [getUserInput@4] getUserInput() called

How you include, initialize, and use a logger will vary depending on the specific logger you select.

Note that conditional compilation directives are also not required using this method, as most loggers have a method to reduce/eliminate writing output to the log. This makes the code a lot easier to read, as the conditional compilation lines add a lot of clutter. With plog, logging can be temporarily disabled by changing the init statement to the following:

We won’t use plog in any future lessons, so you don’t need to worry about learning it.

As an aside...

If you want to compile the above example yourself, or use plog in your own projects, you can follow these instructions to install it:

First, get the latest plog release:

  • Visit the plog repo.
  • Click the “releases” tab (it’s in the same row as “commits”, “branches”, “packages”, etc…)
  • Under the release tagged as “latest release” on the left, click the link “Source code (zip)” to download the latest release.

Next, unzip the entire archive to <anywhere> on your hard drive.

Finally, for each project, set the <anywhere>\plog-<version>\include\ directory as an include directory inside your IDE. There are instructions on how to do this for Visual Studio here: A.2 -- Using libraries with Visual Studio and Code::Blocks here: A.3 -- Using libraries with Code::Blocks.


3.6 -- Using an integrated debugger: Stepping
Index
3.4 -- Basic debugging tactics

51 comments to 3.5 — More debugging tactics

  • 19/08/2020 How to install and use plog (Visual Studio 2019)
    I'm not an English speaker, sorry for the mistakes

    1. Download the repository in .zip https://github.com/SergiusTheBest/plog
    2. Extract the .zip
    3. Find a folder named 'include' and copy it
    4. Go to your project and paste the include folder into your project
    (you have to paste the include folder in the same folder you have the main.cpp)

    The structure of my project looks like this
    LearnCpp
    -- LearnCpp
    ----  main.cpp
    ----  include
    ------   Log.h
    ------   ...(other files and folders)

    5. Go to Properties-> C/C++ -> General -> Additional Include Directories
    6. In the empty field you must write "  $(ProjectDir)include "
    7. Copy this code into main.cpp
    8. Run code and check if this works
    9. If everything goes well a hello.txt should appear in your project files

  • Pionoplayer

    Having a good time with the stuff so far, but plog is just a pain in the neck to try and get to work. After looking through the comments, I'm seeing that I'm not the only one failing to make it work, so two complaints:

    1. plog is not a good recommendation. Especially not for newbies. It starts out broken and is way too fiddly to fix.

    2. Don't link to chapter A.2 unless you're going to fix it up soon, it's literally useless right now since (judging from the comments on it) the method it tells you to utilize no longer exists.

  • I'm using Visual Studio Code and I can't get plog library working. Somehow it can't find the plog-library. I've installed plog through the vcpkg package-manager. The complete library is installed. I've add "includePath" to "c_cpp_properties.json";

    It keeps complaining "plog/Log.h file not found". The include folder contains plog-libary. When I copy the complete libary to the root of the project, plog.Log.h is found BUT it starts complaining about plog.Logger.h not found (include in Log.h). I'm already fiddling for 2 nights in VS Code to get this library running. Any pointers?

    • nascardriver

      vscode is a text editor with fancy plugins. You can probably use a plugin the invoke a compiler with options for you, but that's not a solution you can use in the long run. Have a look at CMake. From the configuration you posted, a CMake file could look like this

      Save as CMakeLists.txt, then create a "build" directory and in the build directory run

      This will generate build files. To compile and run your program, run (Still in the build directory)

      You'll still need the "includePath" in "c_cpp_properties.json". That's what vscode uses for code completion and other things.

      If you want to use vscode's shortcuts, you can create a task and debug configuration to run these commands for you.

      • Thanks for your reply!

        It seems you have to append /** to includePath argument in c_cpp_properties.json so Intellisense will recursively search for header files. He seems okay... not.. after I try to compile code it will show an inline error "plog/log.h not found" For heaven sake again!
        When Googling a bit more I found others have exactly the same problem. It seems you also have to add library as an argument to compiler-file, tasks.json that is.

        So for others facing the same problem. Here are 2 snippets which WILL compile this chapter in vscode and add a Logfile.txt to project folder;

        snippet tasks.json;

        Snippet c_cpp_properties.json;

        Replace path "/Users/raymond/vcpkg/installed/x64-osx/include" to the absolute path of the plog directory. And for Windows I believe path is all backslashes.

  • sami

    I got lots of errors while trying to compile it? I included all .h files and the code should be working, but all errors are mentioned to line including "LOGD << "main() called".

    How should I fix them?

    • sami (RESOLVED)

      Hi again,
      If anyone got the errors above as I did, please try to download the version 1.1.5 not 1.1.4
      When you clicked on the "latest version" tag, version 1.1.4 is automatically downloaded. I posted the issue on Plog git-hub community, and it turned out that I should have downloaded version 1.1.5 where that bug was fixed!  Now I got no compilation error.

  • sami

    1) "you’ll either need to remove them, or comment them out. Then if you want them again later, you’ll have to add them back, or uncomment them."

    2) "Now we can enable debugging simply by commenting / uncommenting #define ENABLE_DEBUG."

    Shouldn't they have "out"?  => " ... or uncomment them out"? => " commenting/ uncommenting out"

  • mohamed

    i made include in VC++ directory as an include directory but giving me all of that

    Severity    Code    Description    Project    File    Line    Suppression State
    Error (active)    E1696    cannot open source file "plog\Log.h"    main    C:\Users\mghozy\source\repos\main\main.cpp    2    
    Error (active)    E0020    identifier "LOGD" is undefined    main    C:\Users\mghozy\source\repos\main\main.cpp    6    
    Error (active)    E0276    name followed by '::' must be a class or namespace name    main    C:\Users\mghozy\source\repos\main\main.cpp    16    
    Error (active)    E0276    name followed by '::' must be a class or namespace name    main    C:\Users\mghozy\source\repos\main\main.cpp    16    
    Error (active)    E0020    identifier "LOGD" is undefined    main    C:\Users\mghozy\source\repos\main\main.cpp    18    
    Error    C1083    Cannot open include file: 'Log.h': No such file or directory    main    C:\Users\mghozy\source\repos\main\main.cpp    2

  • Kleber

    Getting an error before compiling in Visual Studio 2019: (I don't know why there is ( .obj ), "I don't enter myself")

    Warning    C26812    The enum type 'plog::Severity' is unscoped. Prefer 'enum class' over 'enum' (Enum.3).    
    Error    LNK1104    cannot open file 'C:\My Libraries\include.obj'    

    Please, Someone may help me? Thanks in advance.

  • Ankur

    Can someone clear my doubt...TIA
    At line #16 "plog::init" is initialized, so it should have local scope under main function.
    How can we use it in line #6 LOGD << "getUserInput() called"; which is residing in other function?

  • phil

    On Code::Blocks. I just copy and pasted the code from lesson 3.5 into the IDE. I get error in the Util.h file.

    C:\Program Files (x86)\CodeBlocks\plog-1.1.4\include\plog\Util.h|151|error: conversion to 'std::__cxx11::basic_string<wchar_t>::size_type' {aka 'long long unsigned int'} from 'int' may change the sign of the result [-Werror=sign-conversion]|

  • Mike

    Hi. I just wanted to point something out I found in the examples. Shouldn't int x be zero initialized just to make it consistent with the best practices that you've mentioned in the previous lessons?

  • Taras

    While compiling the code <plog/Log.h> on CodeBlocks got a bulk of errors kind like
    ....code_blocks\test\plog\include\plog\Util.h|254|error: '::_wsopen' has not been declared|

  • Omran

    hello , in as an aside... list there is a link to how to use libraries in visual studio but that lesson is too old :)
    i wish that you can update :) , appreciated !!!

  • Michael

    I downloaded plog 1.1.4, used Visual Studio 2019 on Windows 10 to try to compile my main file, and got some obscure errors about "this", "__if_exists", and "__if_not_exists" which I traced back to Log.h:

    I was unable to find anything online confirming this, but it seems to me that my compiler doesn't have support for __if_exists. I edited this part of the header file to leave only `#define PLOG_GET_THIS() 0` which fixed the compile issue for me.

    BTW Alex you should probably mention which directory the log file shows up in :)

  • Raton

    Hello. I tried to use the Plog logger, but I ran into a problem. Here's what I did:

    1) Download the .zip file
    2) Copy the "plog" file from that .zip file to my project file (the one with my code files)
    3) #include "plog/Log.h" in one of my code files

    But then the compiler tells me that it can't find "plog.Logger.h". I figured out that it was actually because of the use of angled brackets instead of quotes in Log.h, so I did the change myself. But then the compiler tells me that it can't find "plog/Appenders/IAppender.h", which is included by Logger.h. Again, it's because of the angled brackets in Logger.h. And the same type of errors kept happening. But does it mean I have to replace the angled brackets with quotes in every Plog header? And why did this problem occur in the first place?

  • the swag man

    when I try to compile

    llvm and gcc throw

    at line 8 and 20... help me please

  • Chayim

    In subject:
    "Conditionalizing your debugging code"
    In the header example "ENABLE-DEBUG"  how is it able to use it as "ifdef" because "ENABLE-DEBUG" has no definition?

  • Chayim

    In the header example, how is it able to use it as "ifdef" because "ENABLE-DEBUG" has no definition?

  • Anderson

    Hey there, quick question.
    In the code snippet below, for example:

    you can clearly notice the difference between line 1 and 2. I would like to know why the iostream library (or file or ...) is surrounded by ankle brackets while the plog/Log.h header file is surrounded by double quotes in this case since it isn't really user defined.

    Is it because the *iostream* library is in the c++ standard library while *plog/Log.h* is a third party library ?

    Also, if it isn't too much to ask, does anyone know where I can see the official standard c++ libraries ?

    • nascardriver

      "" is used for files in your project director, <> for system files or files that you added to the include path (Both "" and <> are implementation-defined, but that's what they usually do).
      "plog/Log.h" is in the project directory, so "" is used.

      > does anyone know where I can see the official standard c++ libraries ?
      https://en.cppreference.com/w/cpp/header

  • sito

    hello! so I'm still learning c++ and I'm using an API which I can't get to work so I need a log file.
    When I try to include the log.h file from plog I get this error: error C1083: Cannot open include file: 'plog/Logger.h': No such file or directory.
    I'm using visual studio 2019 and I've tried going to properties, c++, general and adding  the directory to aditional include directorys. I then did the same but for vc++ directorys so that if the header file is not found in the project directory it would go on and search in the directory where plog is located. Despite me doing this and using #include "Log.h" the error won't go away. Any suggestions on what i can do to fix this?

  • Kyrollos

    I got an error in "Util.h" when I tried to compile my project:
    plog\Util.h|164|error: '_vscwprintf' was not declared in this scope|

  • Austin G

    Output from the logger mentions "main@22" and "getUserInput@10" while those code lines were originally line 18 and line 6 respectively in the code file. Is this anything relevant or just a peculiarity of this particular logger?

    • Alex

      Just a error on my part. I removed an extraneous function from the example which shifted the line numbers, but I forget to update the logger output. Thanks for pointing this out!

  • Darshan K

    Getting an error before compiling in Visual Studio 2019 (I wrote my own program quite similar to this) saying: "namespace "plog" has no member "init"". The program runs properly however.

    My code:

    Another issue is that there is no newline between lines in the log file.

    Code does not compile when I copy-paste the program given in the tutorial.

    How to fix these issues?

  • Manash Das

    Hi Alex,
    As you have mentioned, in a multi-file program #define ENABLE_DEBUG can go into a header file.
    Can you please write code for that header file?

  • Yoel

    In visual studio 2019 you need to include the "plog" directory by Project-> Properties -> C\C++ -> General -> Additional Include directories -> <path to "plog" not including itself>.

    This is because the code references the "plog" directory

  • Red Lightning

    "Log files can also easily sent to other people for diagnosis"
    Syntax error: missing "be".

  • jaffaman

    Got this working in Atom no worries.

    I am running MinGW to compile.

    Steps:
    1. Download zip from https://github.com/SergiusTheBest/plog
    2. Extract files and copy plog folder (~\plog-master\include) to folder (~MinGW\include).
    3. Follow instructions in readme from github.

  • Ram Rasia

    plog library didn't work in MacOSx.

    In file included from CPlusPlusTutorial.cpp:3:
    ./plog/Log.h:7:10: fatal error: 'plog/Logger.h' file not found
    #include <plog/Logger.h>
             ^~~~~~~~~~~~~~~
    1 error generated.

    Angle brackets cause a problem. I think so it should be double quotes.

  • Dong

    In the "Plog strategy" example, I type this code and run it in Visual Studio 2013 and DevC++. Both of them makes error about this code.
    - In Dev C++, [Error] plog/Log.h: No such file or directory.
    - In Visual Studio, first error is the same. The second error is: name followed by '::' must be a class or namespace name. It the same error in Dev C++. I donot know where "plog/Log.h". Thanks for your help.

    • Alex

      You need to get the Log.h file and place it appropriately on your system. I added some instruction to the lesson about how to do this.

  • WSLaFleur

    Since there are no comments on this lesson, I just wanted to take a second to say thanks for making these. This is a decent example, since you haven't really touched on utilizing third-party resources much yet.

Leave a Comment

Put all code inside code tags: [code]your code here[/code]