Standard C++ objects and other concerns

Hello.

Two issues of note.

The first is the most important, and it has two parts. For some reason, when the ROOT interpreter breaks, 60-70% it tells me what is wrong in a nice fashion, usually by pointing out the function that has the problem.

The other 40-30% it segfaults. Usually in the wrong place.

Don’t get me wrong, I don’t think segfaults are necessarily bad things, but they are when you are using an interpreter. A segfault, to me, indicates that the interpreter did something wrong, not the program. Yet most of the time, the problem is in my program, not the interpreter.

This has led to other problems, like breaking the ssh pipe output (Character echo no longer works). Another issue for another time.

Perhaps even more disturbingly, these faults occur after where the real problem is. If I’m to follow the output of the program, and then omit the offending line, then rerun. The offending line is well before the point of stopped execution.

So let me come to the point. How do I avoid this? What kind of serious debugging facilities do I have available to me, because given the above issue, scattered cout/cerr statements don’t work. Maybe more importantly, since 60-70 things work nicely, how do I go about avoiding the segfaults?

Secondly, allow to me to ask why standard C++ objects cause so many problems. The most recent problem of the above variety that I had was caused by a ifstream object, which for all I can tell, was called and used correctly.

        sprintf(file,"%s/netMeyer1024_L%1d.dat",nodedir,i);
        ifstream test(file,fstream::in)
        if(!test){
            ...
        }

Now, I may have done something incorrectly, but I can’t tell because the interpreter won’t tell me that.

I’m sorry if I sound accusing, but I’m frustrated with the lack of options. Any help/advice would be appreciated. Thanks.[/code]

Hi,

there are several issues here. One is that CINT cannot just complain when there is an error - it needs to do something along the lines of exception handling. Think of CINT realizing that it is supposed to dereference a pointer of value 0, which interpreting a function that is called as part of a for loop etc. It needs to remember that there is an error, then finish the function call, the for loop (which are all regular C++ function calls inside CINT) and then, at the end, so to say at the prompt level, complain. And rememebr that e.g. objects that were created in the parts not executed because of the 0-pointer are in fact invalid and need to be removed, etc. Sometimes CINT fails with either one or both of that. We do plan on improving that; especially the improved error handling mechanism (which also involves interpreted and compiled exception handling) is on our wish list.

I’m using CINT for physics myself, so I know what you are talking about. So here is my suggestion: add a “+”. Instead of calling
.x mycode.C
you just do
.x mycode.C+
The “+” makes CINT compile and link your code using your system’s compiler. Your code gets then loaded into ROOT as a library. That way you will get compiler errors you are used to, and you will get exceptions that you can trace, and you can even debug your code using standard debuggers.

Sorry it’s such a frustrating experience; I hope the “+” helps and you are welcome to check back on CINT once a while to see whether we are making progress.

Cheers, Axel.

Hi Axel. Thanks for your response.

I will try what you have suggested.

As far as your example, I understand that CINT is (as all things are) always in development. I appreciate your example, but it is curious to me. Why, when CINT finds a null pointer, it does not immediately throw the equivalent of a Null Pointer Exception/Error (which I suppose is, in fact, a stack trace in the case of C). If you find a null pointer inside of a function inside a loop, then it is distinctly possible that there is a problem with the function or loop, so why let it continue to run? Perhaps I’m misunderstanding your example, and I’d very much like to understand how this works, so I can work more efficiently with ROOT.

Sorry for the confusion.

PS. I still don’t understand why the basic stream object broke the interpreter.