Re: Segfault: function as parameter

From: Philippe Canal <pcanal_at_fnal.gov>
Date: Mon, 17 May 2010 13:16:42 -0500


Hi Vassili,

Passing function pointer back and forth through CINT has some subtleties.

The "address" used for a compiled function when in CINT is not the actual address of the function but instead is the address of the wrapper needed to convert the argument from the interpreter format to the compiled code format (those wrapper are part of the dictionary).

In addition, if you are writing a function that can take a function pointer as argument and you want to be able to call this function (i.e. your callfunc) from the interpreter you need to make sure to handle the case where the passed parameter is an interpreted function. In this case the "address" used (for the interpreted function) is an internal reference that can not be used directly by compile code.

To correctly add this support you will need to add an overload of your callfunc that takes a void*, this void* overload will be called from CINT if you pass any function pointer. You can then use TMethodCall to indirectly call the function.

Cheers,
Philippe.

On 5/17/10 11:49 AM, Vassili Maroussov wrote:
> Dear ROOTers,
>
> here is the code which causes the segmentation violation:
>
> //file: callfunc.C
> #include <iostream>
> using namespace std;
>
> void printit()
> {
> cout << "Here we are." << endl;
> }
>
> void callfunc(void (*func)())
> {
> (*func)();
> }
> //EOF
>
> Here is the ROOT session:
>
> *******************************************
> * *
> * W E L C O M E to R O O T *
> * *
> * Version 5.26/00b 9 February 2010 *
> * *
> * You are welcome to visit our Web site *
> * http://root.cern.ch *
> * *
> *******************************************
>
> ROOT 5.26/00b (tags/v5-26-00b_at_32327, Feb 11 2010, 14:21:13 on
> linuxx8664gcc)
>
> CINT/ROOT C/C++ Interpreter version 5.17.00, Dec 21, 2008
> Type ? for help. Commands must be C++ statements.
> Enclose multiple statements between { }.
> root [0] .L callfunc.C++
> Info in <TUnixSystem::ACLiC>: creating shared library
> /home/vmarouss/fluka_projects/ROOT_Code/./callfunc_C.so
> root [1] callfunc(printit)
> Here we are.
>
> *** Break *** segmentation violation
>
>
>
> ===========================================================
> There was a crash.
> This is the entire stack trace of all threads:
> ===========================================================
> #0 0x00000030980a48fe in waitpid () from /lib64/libc.so.6
> #1 0x000000309803e2b9 in do_system () from /lib64/libc.so.6
> #2 0x00007f22dead60af in TUnixSystem::StackTrace() () from
> /usr/local/ROOT/5.26.00b/lib/libCore.so
> #3 0x00007f22dead7014 in TUnixSystem::DispatchSignals(ESignals) ()
> from /usr/local/ROOT/5.26.00b/lib/libCore.so
> #4 <signal handler called>
> #5 0x00007f22ddfd0d2a in G__setnull () from
> /usr/local/ROOT/5.26.00b/lib/libCint.so
> #6 0x00007f22dd248d41 in G__callfunc_C_ACLiC_dict__0_1087(G__value*,
> char const*, G__param*, int) ()
> from /home/vmarouss/fluka_projects/ROOT_Code/./callfunc_C.so
> #7 0x00007f22dd248a6c in G__callfunc_C_ACLiC_dict__0_1088(G__value*,
> char const*, G__param*, int) ()
> from /home/vmarouss/fluka_projects/ROOT_Code/./callfunc_C.so
> #8 0x00007f22ddf34c6e in Cint::G__ExceptionWrapper(int (*)(G__value*,
> char const*, G__param*, int), G__value*, char*, G__param*, int) ()
> from /usr/local/ROOT/5.26.00b/lib/libCint.so
> #9 0x00007f22ddfd41a1 in G__execute_call () from
> /usr/local/ROOT/5.26.00b/lib/libCint.so
> #10 0x00007f22ddfd5a12 in G__call_cppfunc () from
> /usr/local/ROOT/5.26.00b/lib/libCint.so
> #11 0x00007f22ddfb357d in G__interpret_func () from
> /usr/local/ROOT/5.26.00b/lib/libCint.so
> #12 0x00007f22ddfa1d0b in G__getfunction () from
> /usr/local/ROOT/5.26.00b/lib/libCint.so
> #13 0x00007f22ddf7e95a in G__getitem () from
> /usr/local/ROOT/5.26.00b/lib/libCint.so
> #14 0x00007f22ddf849f6 in G__getexpr () from
> /usr/local/ROOT/5.26.00b/lib/libCint.so
> #15 0x00007f22de001ada in G__exec_statement () from
> /usr/local/ROOT/5.26.00b/lib/libCint.so
> #16 0x00007f22ddf6b27e in G__exec_tempfile_core () from
> /usr/local/ROOT/5.26.00b/lib/libCint.so
> #17 0x00007f22ddf6b51e in G__exec_tempfile_fp () from
> /usr/local/ROOT/5.26.00b/lib/libCint.so
> #18 0x00007f22de00d159 in G__process_cmd () from
> /usr/local/ROOT/5.26.00b/lib/libCint.so
> #19 0x00007f22dd465196 in TCint::ProcessLine(char const*,
> TInterpreter::EErrorCode*) ()
> from /usr/local/ROOT/5.26.00b/lib/libMetaTCint.so
> #20 0x00007f22dea28221 in TApplication::ProcessLine(char const*, bool,
> int*) ()
> from /usr/local/ROOT/5.26.00b/lib/libCore.so
> #21 0x00007f22dd8d466a in TRint::HandleTermInput() () from
> /usr/local/ROOT/5.26.00b/lib/libRint.so
> #22 0x00007f22dead427e in TUnixSystem::CheckDescriptors() () from
> /usr/local/ROOT/5.26.00b/lib/libCore.so
> #23 0x00007f22dead4421 in TUnixSystem::DispatchOneEvent(bool) () from
> /usr/local/ROOT/5.26.00b/lib/libCore.so
> #24 0x00007f22dea75316 in TSystem::InnerLoop() () from
> /usr/local/ROOT/5.26.00b/lib/libCore.so
> #25 0x00007f22dea7748b in TSystem::Run() () from
> /usr/local/ROOT/5.26.00b/lib/libCore.so
> #26 0x00007f22dea2687f in TApplication::Run(bool) () from
> /usr/local/ROOT/5.26.00b/lib/libCore.so
> #27 0x00007f22dd8d4a05 in TRint::Run(bool) () from
> /usr/local/ROOT/5.26.00b/lib/libRint.so
> #28 0x000000000040106c in main ()
> ===========================================================
>
>
> The crash is most likely caused by a problem in your script.
> Try to compile it (.L myscript.C+g) and fix any errors.
> If that does not help then please submit a bug report at
> http://root.cern.ch/bugs. Please post the ENTIRE stack trace
> from above as an attachment in addition to anything else
> that might help us fixing this issue.
>
>
> Root > .q
>
> What is illegal in the callfunc.C or in the ROOT session?
>
> Regards,
>
> Vassili
>
>
Received on Mon May 17 2010 - 20:16:47 CEST

This archive was generated by hypermail 2.2.0 : Mon May 17 2010 - 23:50:02 CEST