ROOT Version: 6.26.10
Platform: Ubuntu 22.04
Compiler: g++ 11.3.0
I’m trying to add a context menu function to a class derived from TLine, using the // *MENU*
comment. The function does show up when opening the context menu, but the moment the function accesses the single parameter read from the dialog I get a segmentation violation. I wrote a simple class to re-create this issue consisting of a header testLine.h
#pragma once
#include <iostream>
#include <string>
#include "TLine.h"
class testLine : public TLine
{
public:
testLine() {}
~testLine() {}
void MenuFunction(const double& lineWidth) { std::cout<<__PRETTY_FUNCTION__<<std::endl; std::cout<<"line width "<<lineWidth<<std::endl; SetLineWidth(lineWidth); } // *MENU*
void Label(const std::string& label) { fLabel = label; }
using TLine::Draw;
void Draw(const double& x, const double& y) { SetX1(x); SetX2(x+y); SetY1(y); SetY2(y-x); TLine::Draw(); }
private:
std::string fLabel{""};
ClassDef(testLine, 1);
};
and an almost empty source file testLine.cxx
#include "testLine.h"
ClassImp(testLine)
I compile the class using the commands
rootcling -f testLineDict.cxx testLine.h LinkDef.h -I. -rml libtestLine.so -rmf testLine.rootmap
g++ -fPIC -c testLineDict.cxx -o testLineDict.o `root-config --cflags`
g++ -fPIC -c testLine.cxx -o testLine.o `root-config --cflags`
g++ -shared -o libtestLine.so testLine.o testLineDict.o
and run the macro lineTest.C
void lineTest()
{
auto c1 = new TCanvas;
std::cout<<"created canvas c1 "<<c1<<std::endl;
auto a = new testLine;
a->Label("test a");
a->Draw(0.1, 0.15);
a->Print();
c1->GetListOfPrimitives()->Print();
}
which gives me this output:
root [0]
Processing lineTest.C...
created canvas c1 0x5574f7756da0
testLine X1=0.100000 Y1=0.150000 X2=0.250000 Y2=0.050000
Collection name='TList', class='TList', size=1
testLine X1=0.100000 Y1=0.150000 X2=0.250000 Y2=0.050000
root [1] void testLine::MenuFunction(const double &)
*** Break *** segmentation violation
line width
===========================================================
There was a crash.
This is the entire stack trace of all threads:
===========================================================
#0 0x00007f82fbd6945a in __GI___wait4 (pid=1955243, stat_loc=stat_loc
entry=0x7ffec7c84418, options=options
entry=0, usage=usage
entry=0x0) at ../sysdeps/unix/sysv/linux/wait4.c:30
#1 0x00007f82fbd6941b in __GI___waitpid (pid=<optimized out>, stat_loc=stat_loc
entry=0x7ffec7c84418, options=options
entry=0) at ./posix/waitpid.c:38
#2 0x00007f82fbccfbcb in do_system (line=<optimized out>) at ../sysdeps/posix/system.c:171
#3 0x00007f82fc4098a4 in TUnixSystem::StackTrace() () from /opt/cern/root/root_v6.26.10/lib/libCore.so.6.26
#4 0x00007f82fc406bb5 in TUnixSystem::DispatchSignals(ESignals) () from /opt/cern/root/root_v6.26.10/lib/libCore.so.6.26
#5 <signal handler called>
#6 0x00007f82df84607d in ?? ()
#7 0x0000000000000004 in ?? ()
#8 0x00007f82f7335a75 in unsigned long long (anonymous namespace)::sv_to<unsigned long long>(cling::Value const&) () from /opt/cern/root/root_v6.26.10/lib/libCling.so
#9 0x00007f82f733c1b8 in TClingCallFunc::exec(void*, void*) () from /opt/cern/root/root_v6.26.10/lib/libCling.so
#10 0x00007f82f72e084a in TCling::Execute(TObject*, TClass*, char const*, char const*, bool, int*) () from /opt/cern/root/root_v6.26.10/lib/libCling.so
#11 0x00007f82f72e0b82 in TCling::Execute(TObject*, TClass*, char const*, char const*, int*) () from /opt/cern/root/root_v6.26.10/lib/libCling.so
#12 0x00007f82fc2e0d3a in TObject::Execute(char const*, char const*, int*) () from /opt/cern/root/root_v6.26.10/lib/libCore.so.6.26
#13 0x00007f82fc3ecf28 in TContextMenu::Execute(TObject*, TFunction*, char const*) () from /opt/cern/root/root_v6.26.10/lib/libCore.so.6.26
#14 0x00007f82e00e2506 in TRootContextMenu::ProcessMessage(long, long, long) () from /opt/cern/root/root_v6.26.10/lib/libGui.so.6.26.10
#15 0x00007f82dffe793d in TGFrame::HandleClientMessage(Event_t*) () from /opt/cern/root/root_v6.26.10/lib/libGui.so.6.26.10
#16 0x00007f82dfff8cd0 in TGFrame::HandleEvent(Event_t*) () from /opt/cern/root/root_v6.26.10/lib/libGui.so.6.26.10
#17 0x00007f82dffa0f0d in TGClient::HandleMaskEvent(Event_t*, unsigned long) () from /opt/cern/root/root_v6.26.10/lib/libGui.so.6.26.10
#18 0x00007f82dffa10af in TGClient::ProcessOneEvent() () from /opt/cern/root/root_v6.26.10/lib/libGui.so.6.26.10
#19 0x00007f82dffa118b in TGClient::HandleInput() () from /opt/cern/root/root_v6.26.10/lib/libGui.so.6.26.10
#20 0x00007f82fc4073e8 in TUnixSystem::DispatchOneEvent(bool) () from /opt/cern/root/root_v6.26.10/lib/libCore.so.6.26
#21 0x00007f82fc3115b2 in TSystem::ProcessEvents() () from /opt/cern/root/root_v6.26.10/lib/libCore.so.6.26
#22 0x00007f82dff9f3dd in TGClient::WaitFor(TGWindow*) () from /opt/cern/root/root_v6.26.10/lib/libGui.so.6.26.10
#23 0x00007f82e00e1510 in TRootContextMenu::Dialog(TObject*, TFunction*) () from /opt/cern/root/root_v6.26.10/lib/libGui.so.6.26.10
#24 0x00007f82fc3ebc18 in TContextMenu::Action(TObject*, TMethod*) () from /opt/cern/root/root_v6.26.10/lib/libCore.so.6.26
#25 0x00007f82e00e25a0 in TRootContextMenu::ProcessMessage(long, long, long) () from /opt/cern/root/root_v6.26.10/lib/libGui.so.6.26.10
#26 0x00007f82dffe793d in TGFrame::HandleClientMessage(Event_t*) () from /opt/cern/root/root_v6.26.10/lib/libGui.so.6.26.10
#27 0x00007f82dfff8cd0 in TGFrame::HandleEvent(Event_t*) () from /opt/cern/root/root_v6.26.10/lib/libGui.so.6.26.10
#28 0x00007f82dffa0ace in TGClient::HandleEvent(Event_t*) () from /opt/cern/root/root_v6.26.10/lib/libGui.so.6.26.10
#29 0x00007f82dffa112d in TGClient::ProcessOneEvent() () from /opt/cern/root/root_v6.26.10/lib/libGui.so.6.26.10
#30 0x00007f82dffa118b in TGClient::HandleInput() () from /opt/cern/root/root_v6.26.10/lib/libGui.so.6.26.10
#31 0x00007f82fc4073e8 in TUnixSystem::DispatchOneEvent(bool) () from /opt/cern/root/root_v6.26.10/lib/libCore.so.6.26
#32 0x00007f82fc311817 in TSystem::Run() () from /opt/cern/root/root_v6.26.10/lib/libCore.so.6.26
#33 0x00007f82fc2a7977 in TApplication::Run(bool) () from /opt/cern/root/root_v6.26.10/lib/libCore.so.6.26
#34 0x00007f82fc6cf38b in TRint::Run(bool) () from /opt/cern/root/root_v6.26.10/lib/libRint.so.6.26
#35 0x00005574f497d2f3 in main ()
===========================================================
I tried finding other issues discussing this problem, but I didn’t see anyone else having this problem. Any idea what I’m doing wrong here? Or is there somewhere all the possible comment flags are explained? I saw some of the root classes using *ARGS=...
to set default values based on members of the class (I think?) and some using *GETTER=...
to do something else (provide the corresponding getter function?), but what these flags exactly do I don’t know.