Debugging a ROOT macro

ROOT Version: 6.26.00
Platform: Ubuntu 20.04.4 LTS
Compiler: g++ (Ubuntu 9.4.0-1ubuntu1~20.04) 9.4.0

Dear ROOT team and users,

As a beginner in ROOT and C language, I am trying to debug a root macro. For this purpose I tried to use the debugging platform that have been provided in [ → debuging-root-scripts-in-eclipse]. Unfortunately I can’t proceed with the debugging because building the code is not successful. I am receiving the following errors upon compiling the “analysis.C” :


#include <TApplication.h>

// TODO: Include your ROOT script below
#include "analysis.C"

int main(int argc, char **argv) {
	// Instantiate TApplication
	TApplication* app = new TApplication("rootEclipse", &argc, argv);

	// TODO: Call your ROOT script entry fiunction

	// Enter the event loop
	// Return success
	return 0;


#include <iostream>
#include "TROOT.h"
#include "DNAVolumeType.hh"
#include <fstream>
#include <sstream>
#include <cstdlib>
#include <TCanvas.h>
#include <TH1.h>
using namespace std;

template<typename T>  
class ThreeVector
	T _x, _y, _z;

	ThreeVector(T x, T y, T z)
	T x() const
		return _x;
	T y() const
		return _y;
	T z() const
	return _z;
	bool operator ==(const ThreeVector<T>& right) const
		return (_x == right._x) && 
			   (_y == right._y) &&
			   (_z == right._z);
	ThreeVector<T>& operator =(const ThreeVector<T>& right) = default;


#if !defined(__CLING__)

class Molecule
    Molecule(string name, 
             int copyNumber, 
             const ThreeVector<double>& position, 
             int strand)
             : fName(name)
             , fCopyNumber(copyNumber)
             , fPosition(position)
             , fStrand(strand)
    string fName;
    string fMaterial;
    int fCopyNumber;
    int fStrand;

    ThreeVector<double> fPosition;

    double fRadius;
    double fRadiusWater;


#if !defined(__CLING__)

std::vector<Molecule> molecule()
    std::vector<Molecule> fMolecules;
    double size;
    string name;
    ifstream file("VoxelStraight.fab2g4dna");
        string msg ="VoxelStraight.fab2g4dna could not be opened";
        throw std::invalid_argument(msg);

   string line;
    while(getline(file, line) )
        istringstream issLine(line);
        string firstItem;
        issLine >> firstItem;
        if("_Size" == firstItem)
            issLine >> size;
        else if("_pl" == firstItem)
            string name;
            issLine >> name;

            string material;
            issLine >> material;

            int strand;
            issLine >> strand;

            int copyNumber;
            issLine >> copyNumber;

            double x;
            issLine >> x;

            double y;
            issLine >> y;

            double z;
            issLine >> z;

            Molecule molecule(name, 
                              ThreeVector<double>(x, y, z), 
    return fMolecules;

void analysis()
	TH1* hist = new TH1D("hist", "hist", 10, 0, 10);
	hist->FillRandom("gaus", 10000);

and the errors are:

/usr/bin/ld: CMakeFiles/root-eclipse.dir/src/main.cpp.o: in function `Molecule::Molecule(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, ThreeVector<double> const&, int)':

/usr/bin/ld: CMakeFiles/root-eclipse.dir/src/main.cpp.o: in function `Molecule::~Molecule()':

/usr/bin/ld: CMakeFiles/root-eclipse.dir/src/main.cpp.o: in function `Molecule::Molecule(Molecule const&)':

analysis.C:63: undefined reference to `vtable for Molecule'

/usr/bin/ld: CMakeFiles/root-eclipse.dir/src/main.cpp.o:([_ZTV11ThreeVectorIdE]+0x28): undefined reference to `ThreeVector<double>::Streamer(TBuffer&)'

analysis.C:55: undefined reference to `ThreeVector<double>::Class()'

Since I am a new user I could not attach the “DNAVolumeType.hh” and the “CMakeList.txt”.

Just in case it could help:
I am using the Geant4-DNA package. The outputs of the example that I am using (dnadamage1) are 2 “.root” files. The final results are obtained using two ROOT macro files: “molecule.C” and “plot.C” through executing:

    gROOT->ProcessLine(".L molecule.C");
    gROOT->ProcessLine(".x plot.C");

Now, In order to be able to debug these codes, I am trying to combine “molecule.C” and “plot.C” into one(the “analysis.C”) as a standalone C++ code. I started with bringing the “molecule.C”, where I am encountering the above mentioned errors. If having the “plot.C” or “molecule.C” could help, I can share them with email.

Many thanks in advance,

I see that you have at least two “undefined reference”. vtable for instance. You should start by that and see why this is not defined. Note declared ? include file missing ? it should be easy to spot.

Dear Olivier,

Many thanks for your response.

I guess my poor knowledge of C programming worsens the problem here. Indeed, I’ve already tried to do quite a lot of research about these errors on the net, but non of the proposed solutions was effective. Some say it’s related to the “shared libraries and modifying the CMake file”, some point to the code itself, and of some modifying the “LinkDef.h”.

Unfortunately I have bot been able to figure it out. So, could you please elaborate your answer a bit more?


Can you post the missing files (CMakeLists…) as text blocks ?

Did you call the macros ROOT_GENERATE_DICTIONARY in your CMakeLists ?

Or instead, download this project see if it compiles, and then see what differences there are wrt yours.

Consider also as an alternative: Coding in ROOT with the horsepower of an F1 - ROOT

Hi Ferhue,

Thank you for your response.

Now that I have been promoted to the trust level by ROOT forum, I can enclose the files.

I am attaching the CMakeLists.txt for your consideration. It seems that in includes the ROOT_GENERATE_DICTIONARY.

CMakeLists.txt (6.3 KB)


The “not defined vtable” should be easy to find. just search the occurrences of vtable in you code.
The definition should be missing.

@couet Missing “vtable” means that ROOT’s C++ interpreter does not know the corresponding class (i.e., a missing dictionary).

1 Like

I think that you are missing to generate the dictionary of the Molecule class that you are inlining now in the .C class. Move it to a separate header and use Dictionary Example · Modern CMake .

I would strongly suggest to use instead these instructions.

That way, you do not need to generate dictionaries or create CMakeLists, etc. You just select your macro from a dropdown menu, and run it.

This is what I see when running your analysis.C from there. No need for CMakeLists or dictionaries, just out of the box:

@ferhue From the first post here, I guess @AliH is using Eclipse IDE,

Ahh ok, but there must be surely something equivalent for Eclipse IDE. Instead of running a TApplication with a complex CMakeList, etc, you could just compile ROOT from Eclipse in Debug Mode, and then run the executable root.exe with the debugger, passing as argument your script name.

Many thanks to everyone for the responses. I am trying to use the very interesting framework that @farhue has built (Coding in ROOT with the horsepower of an F1 - ROOT). Now, I am able to run the “analysis.C”, but not yet the “debugging” capability.

I followed the instructions:

  • I built the ROOT in the debug mode,
  • selected the “root.exe” in the “Run configuration” (Projects → Run settings ->Run),
  • introduced the analysis.C as for the “command line arguments”,
  • specified the directory in which the “analysis.C” resides, as the “working directory”,

Now, when I click the “play-bug” icon, the code runs through to the end and the output plot shows up. When I press the “F5” control key, the debugging tools are activated, but I don’t have any control on the “analysis.C”. Even after I open the “analysis.C” and put a breakpoint, nothing happens (does not stop at the breakpoint). Instead, the pointer stops somewhere in the “TUnixSystem.cxx”.

So, could you please share how you get to “debug the analysis.C” right out of the box" as you had mentioned in your post? What am I missing here? I am attaching two snapshots of what I’m encountering for your consideration.

You are welcome.

Not sure what’s happening. Try the following:
instead of
in the command line arguments.

The + is to precompile.
The ‘g’ is optional, to add debug symbols.

This is what I get:

Oh, I think I see what happened.
You clicked first on the Play-Bug button, and only later set the breakpoint, right?
Do it the other way round.
F5 is only doing play-pause. So if you click on that after the script has run, your program is hanging on the UnixSelect function, which means, wait for user to give some input (e.g. zoom my axis, etc.).

You need to set the breakpoint before clicking F5 (or the PlayBug icon).

Thank you for the prompt response!
Unfortunately non of the solutions worded! adding the “+g”, “g”, or “+”.

Also I set the breakpoint before hitting the F5, but the same story happens. I even tried it with he “hsimple.C” in ROOT-path/tutorials/. Again the code is running to the end and without any stop at the breaking point.

what I did is:

  • loaded the ROOT project
  • opened the “analysis.C” and set the breakpoint.
  • finally the F5.

could this error be the cause:

 Clang Code Model: Error: The clangbackend process has finished unexpectedly and was restarted.

after I set the breakpoint, this error appears repeatedly at the “General Messages”.

Yes, that could be indeed the problem.

What version of QtCreator are you using? It works for me on QtCreator 5.0.3 (on Ubuntu 18).

See [QTCREATORBUG-20171] Repeated clangbackend crashing (clang tidy related stacktraces) - Qt Bug Tracker

Now the problem is solved!

I removed my QtCreator (the version was 4.10) and installed the 6.0.2 So the Clang Code Model : Error is resolved now. For everyone who might read this thread in the future, I used these instructions to have a clear, straightforward QtCreator installation:

After that, to be able to debug the code I used the analysis.C+ as the “command line argument” input (set the breakpoint in the target code before firing the debugger, play-bug or F5).

The point is that: by using the analysis.C as the “command line input” the debugger does not stop at the breakpoint and skips over the breakpoints, but the addition of “+” resolves that.

Huge thanks to every one, especially @ferhue for his very helpful instructions:

1 Like