neuronsimulator / nrn

NEURON Simulator
http://nrn.readthedocs.io
Other
376 stars 113 forks source link

Thread-safe GLOBALs in NET_RECEIVE. #2908

Open 1uc opened 3 weeks ago

1uc commented 3 weeks ago

The following MOD file:

NEURON {
    POINT_PROCESS ThreadVar
    GLOBAL gw
    THREADSAFE
}

ASSIGNED {
    gw
}

INITIAL {
    gw=0
}

NET_RECEIVE(weight (uS)) {
    gw = gw + weight
}

contains a "thread variable", i.e. global variable that's written to along with the promise that everything is THREAD_SAFE.

It generates the following code:

#define _gth         0
#define gw_ThreadVar _thread1data[0]
#define gw           _thread[_gth].get<double*>()[0]

...

static void _net_receive(Point_process* _pnt, double* _args, double _lflag) {
    Prop* _p;
    Datum* _ppvar;
    Datum* _thread;
    NrnThread* _nt;
    _nrn_mechanism_cache_instance _ml_real{_pnt->_prop};
    auto* const _ml = &_ml_real;
    size_t const _iml{};
    _thread = nullptr;
    _nt = (NrnThread*) _pnt->_vnt;
    _ppvar = _nrn_mechanism_access_dparam(_pnt->_prop);
    // ...
    { gw = gw + _args[0]; }
}

which should result in a nullptr dereference when accessing gw, because _thread == nullptr.