.L <file> followe by LoadMacro(<file) crashes

Not sure if this is a bug or a feature, but as I just spent a day working out what has been going on I thought I would post this, if only as a warning for others. I have discovered that the following sequence causes a crash:
gROOT->ProcessLine(".L hyperk_esd_html_summary.C+");
gROOT->LoadMacro(“hyperk_esd_html_summary.C”)
HtmlSummary* fgHtmlSummary = new HtmlSummary(“Alice Event Display Summary Table”);

the macro in this example is taken from the tutorials/eve area, but I don’t think that is relevant.

Of course the two lines in question were in widely separate places in my code, which is why it took me so long to find the cause.

I was using root 5.34/23.

Here is the crash traceback …

*** Break *** segmentation violation

===========================================================
There was a crash.
This is the entire stack trace of all threads:

#0 0x0000003b942ac68e in waitpid () from /lib64/libc.so.6
#1 0x0000003b9423e609 in do_system () from /lib64/libc.so.6
#2 0x00007f7b8ade5ee8 in TUnixSystem::StackTrace() () from /t2k/hyperk/software/hyperk-releases/v1r1.1/root/lib/libCore.so
#3 0x00007f7b8ade4d63 in TUnixSystem::DispatchSignals(ESignals) () from /t2k/hyperk/software/hyperk-releases/v1r1.1/root/lib/libCore.so
#4
#5 0x00007f7b8a06d4fe in G__baseconstructor () from /t2k/hyperk/software/hyperk-releases/v1r1.1/root/lib/libCint.so
#6 0x00007f7b8a06e0bb in G__baseconstructorwp () from /t2k/hyperk/software/hyperk-releases/v1r1.1/root/lib/libCint.so
#7 0x00007f7b8a064e58 in G__interpret_func () from /t2k/hyperk/software/hyperk-releases/v1r1.1/root/lib/libCint.so
#8 0x00007f7b8a051c6c in G__getfunction () from /t2k/hyperk/software/hyperk-releases/v1r1.1/root/lib/libCint.so
#9 0x00007f7b8a081428 in G__new_operator () from /t2k/hyperk/software/hyperk-releases/v1r1.1/root/lib/libCint.so
#10 0x00007f7b8a034b68 in G__getexpr () from /t2k/hyperk/software/hyperk-releases/v1r1.1/root/lib/libCint.so
#11 0x00007f7b8a0222bb in G__define_var () from /t2k/hyperk/software/hyperk-releases/v1r1.1/root/lib/libCint.so
#12 0x00007f7b8a0b2f5c in G__exec_statement () from /t2k/hyperk/software/hyperk-releases/v1r1.1/root/lib/libCint.so
#13 0x00007f7b8a01bd51 in G__exec_tempfile_core () from /t2k/hyperk/software/hyperk-releases/v1r1.1/root/lib/libCint.so
#14 0x00007f7b8a01c04e in G__exec_tempfile_fp () from /t2k/hyperk/software/hyperk-releases/v1r1.1/root/lib/libCint.so
#15 0x00007f7b8a0bf479 in G__process_cmd () from /t2k/hyperk/software/hyperk-releases/v1r1.1/root/lib/libCint.so
#16 0x00007f7b8ada6d26 in TCint::ProcessLine(char const*, TInterpreter::EErrorCode*) () from /t2k/hyperk/software/hyperk-releases/v1r1.1/root/lib/libCore.so
#17 0x00007f7b8ad0d6b0 in TApplication::ProcessLine(char const*, bool, int*) () from /t2k/hyperk/software/hyperk-releases/v1r1.1/root/lib/libCore.so
#18 0x00007f7b8a95afab in TRint::HandleTermInput() () from /t2k/hyperk/software/hyperk-releases/v1r1.1/root/lib/libRint.so
#19 0x00007f7b8ade33fe in TUnixSystem::CheckDescriptors() () from /t2k/hyperk/software/hyperk-releases/v1r1.1/root/lib/libCore.so
#20 0x00007f7b8ade36e3 in TUnixSystem::DispatchOneEvent(bool) () from /t2k/hyperk/software/hyperk-releases/v1r1.1/root/lib/libCore.so
#21 0x00007f7b8ad661a6 in TSystem::InnerLoop() () from /t2k/hyperk/software/hyperk-releases/v1r1.1/root/lib/libCore.so
#22 0x00007f7b8ad67c2b in TSystem::Run() () from /t2k/hyperk/software/hyperk-releases/v1r1.1/root/lib/libCore.so
#23 0x00007f7b8ad0a29f in TApplication::Run(bool) () from /t2k/hyperk/software/hyperk-releases/v1r1.1/root/lib/libCore.so
#24 0x00007f7b8a95c534 in TRint::Run(bool) () from /t2k/hyperk/software/hyperk-releases/v1r1.1/root/lib/libRint.so
#25 0x000000000040102c in main ()

Hi,

Note that the pattern:gROOT->ProcessLine(".L hyperk_esd_html_summary.C+"); gROOT->LoadMacro("hyperk_esd_html_summary.C")is a bit odd as it request to reload using the interpreter code that was already loaded using compiled code (so the net effect would be to negate the first command (and get a more buggy slower version of it) …

i.e the right course of action is to remove one of the two calls.

Cheers,
Philippe.

Well obviously, but as I said the two lines were in separate places in the code, so the illogicality was easily missed. It took a lot of detective work to narrow it down to this.

You could try to “protect” your code (maybe, in addition to “.C” and “_C.so”, you also need to add conditions that are relevant for MacOS and/or Windows, which depends on what ACLiC creates on these systems):

// ...
if (!( gInterpreter->IsLoaded("hyperk_esd_html_summary.C") ||
       gInterpreter->IsLoaded("hyperk_esd_html_summary_C.so") ))
  gROOT->ProcessLine(".L hyperk_esd_html_summary.C++");
// ...
if (!( gInterpreter->IsLoaded("hyperk_esd_html_summary.C") ||
       gInterpreter->IsLoaded("hyperk_esd_html_summary_C.so") ))
  gROOT->LoadMacro("hyperk_esd_html_summary.C");
// ...