: minimal.mod
NEURON {
SUFFIX minimal
}
FUNCTION f() {
f = 1
}
Compiling it with NMODL works:
$ nrnivmodl -nmodl $(which nmodl) minimal.mod
[NMODL][warning] Code generation with NMODL is pre-alpha, lacks features and is intended only for development use
/Users/jelic/software/nmodl-clean/test/usecases/empty
cfiles =
Mod files: "minimal.mod"
Creating 'arm64' directory for .o files.
MODOBJS= ./minimal.o
-> Compiling mod_func.cpp
-> NMODL ../minimal.mod
-> Compiling /arm64/minimal.cpp
=> LINKING shared library "/arm64/./libnrnmech.dylib"
=> LINKING executable "/arm64/./special" LDFLAGS are:
ld: warning: ignoring duplicate libraries: '-lnrnmech'
Successfully created arm64/special
Unfortunately, running the following Python script:
# sim.py
from neuron import h
s = h.Section()
s.insert("minimal")
h.f_minimal()
causes a segfault when running via nrniv sim.py (one can equivalently run with python sim.py, but then debugging is cumbersome).
Running under the LLDB debugger reveals:
(lldb) run
Process 39954 launched: '/nrn/build-arm64/install/bin/nrniv' (arm64)
NEURON -- VERSION 9.0a-243-g30b42a1b8+ master (30b42a1b8+) 2024-05-14
Duke, Yale, and the BlueBrain Project -- Copyright 1984-2022
See http://neuron.yale.edu/neuron/credits
loading membrane mechanisms from arm64/.libs/libnrnmech.so
Additional mechanisms from files
"minimal.mod"
Process 39954 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
frame #0: 0x00000001001dceb8 libnrnmech.so`double* neuron::cache::MechanismRange<1ul, 0ul>::data_array<0, 1>(this=0x000000016fdfdfd8, instance=0) at mechanism_range.hpp:87:26
84 [[nodiscard]] double* data_array(std::size_t instance) {
85 static_assert(variable < NumFloatingPointFields);
86 // assert(array_size == m_data_array_dims[variable]);
-> 87 return std::next(m_data_ptrs[variable], array_size * (m_offset + instance));
88 }
89
90 template <int variable, int array_size>
Target 0: (nrniv) stopped.
actually calls neuron::cache::MechanismInstance, which has this code snippet:
MechanismInstance(Prop* prop)
: base_type{_nrn_mechanism_get_type(prop), mechanism::_get::_current_row(prop)} {
if (!prop) {
// grrr...see cagkftab test where setdata is not called(?) and extcall_prop is null(?)
return;
}
This seems to originate from this NEURON commit, and is where I sort of lost track of what's going on.
Going back to the drawing board, we can instead call this Python script:
from neuron import h, gui
s = h.Section()
s.insert("minimal")
s(0.5).minimal.f() # <--- instead of `h.f_minimal()`
which doesn't segfault, so the HOC call doesn't work, but its Section equivalent does. Stopping at _npy_f (I guess the NEURON Python equivalent of _hoc_f?), we get:
I don't know if this will help but the same issue was very longstanding with nocmodl and was fixed in
neuronsimulator/nrn#2460
Also see neuronsimulator/nrn#2475
Below is a preliminary writeup about a segfault caused by calling
h.<function>_<suffix>
in a Python script.Take the following mod file:
Compiling it with NMODL works:
Unfortunately, running the following Python script:
causes a segfault when running via
nrniv sim.py
(one can equivalently run withpython sim.py
, but then debugging is cumbersome). Running under the LLDB debugger reveals:The full backtrace being:
The issue seems to be that we are trying to dereference a
nullptr
:Going up a couple of frames:
Note that
_ml_real
doesn't have any data in it:The entire definition of
_hoc_f
is as follows:Going down the rabbit hole, it seems
_local_prop
is anullptr
, and the call to:actually calls
neuron::cache::MechanismInstance
, which has this code snippet:This seems to originate from this NEURON commit, and is where I sort of lost track of what's going on.
Going back to the drawing board, we can instead call this Python script:
which doesn't segfault, so the HOC call doesn't work, but its
Section
equivalent does. Stopping at_npy_f
(I guess the NEURON Python equivalent of_hoc_f
?), we get:which is not a
nullptr
, so maybe it has something to do with this?