BlueBrain / nmodl

Code Generation Framework For NEURON MODeling Language
https://bluebrain.github.io/nmodl/
Apache License 2.0
55 stars 15 forks source link

LLVM IR segfault with simple mod file #525

Closed pramodk closed 3 years ago

pramodk commented 3 years ago

Hello @georgemitenkov ,

I think this just might be because of some missing pieces but I thought good to create ticket anyway:

TITLE hh.mod   squid sodium, potassium, and leak channels

UNITS {
    (mA) = (milliamp)
    (mV) = (millivolt)
    (S) = (siemens)
}

NEURON {
    SUFFIX hh
    USEION na READ ena WRITE ina
    USEION k READ ek WRITE ik
    NONSPECIFIC_CURRENT il
    RANGE gnabar, gkbar, gl, el, gna, gk
    RANGE minf, hinf, ninf, mtau, htau, ntau
    THREADSAFE : assigned GLOBALs will be per thread
}

PARAMETER {
    gnabar = .12 (S/cm2)    <0,1e9>
    gkbar = .036 (S/cm2)    <0,1e9>
    gl = .0003 (S/cm2)  <0,1e9>
    el = -54.3 (mV)
}

STATE {
    m h n
}

ASSIGNED {
    v (mV)
    celsius (degC)
    ena (mV)
    ek (mV)
    gna (S/cm2)
    gk (S/cm2)
    ina (mA/cm2)
    ik (mA/cm2)
    il (mA/cm2)
    minf hinf ninf
    mtau (ms) htau (ms) ntau (ms)
}

BREAKPOINT {
    SOLVE states METHOD cnexp
    gna = gnabar*m*m*m*h
    ina = gna*(v - ena)
    gk = gkbar*n*n*n*n
    ik = gk*(v - ek)
    il = gl*(v - el)
}

DERIVATIVE states {
     m' =  (minf-m)/mtau
     h' = (hinf-h)/htau
     n' = (ninf-n)/ntau
}

and trying LLVM IR on LLVM branch gives:

$ ./bin/nmodl hh.mod llvm --ir
[NMODL] [info] :: Processing hh.mod
[NMODL] [info] :: Running symtab visitor
[NMODL] [info] :: Running CVode to cnexp visitor
[NMODL] [info] :: Running LOCAL to ASSIGNED visitor
[NMODL] [info] :: Running code compatibility checker
[NMODL] [info] :: Running verbatim rename visitor
[NMODL] [info] :: Running KINETIC block visitor
[NMODL] [info] :: Running STEADYSTATE visitor
[NMODL] [info] :: Parsing Units
[NMODL] [info] :: Running cnexp visitor
[NMODL] [info] :: Running C backend code generator
[NMODL] [info] :: Running LLVM backend code generator
[NMODL] [info] :: Running CodegenLLVMHelperVisitor
VOID nrn_state_hh(){
    INTEGER id
    for(id = 0; id<node_count; id = id+1) {
        INTEGER node_id, ena_id, ek_id
        DOUBLE v
        node_id = node_index[id]
        ena_id = ion_ena_index[id]
        ek_id = ion_ek_index[id]
        v = voltage[node_id]
        ena[id] = ion_ena[ena_id]
        ek[id] = ion_ek[ek_id]
        m[id] = m[id]+(1.0-exp(dt*((((-1.0)))/mtau[id])))*(-(((minf[id]))/mtau[id])/((((-1.0)))/mtau[id])-m[id])
        h[id] = h[id]+(1.0-exp(dt*((((-1.0)))/htau[id])))*(-(((hinf[id]))/htau[id])/((((-1.0)))/htau[id])-h[id])
        n[id] = n[id]+(1.0-exp(dt*((((-1.0)))/ntau[id])))*(-(((ninf[id]))/ntau[id])/((((-1.0)))/ntau[id])-n[id])
    }
Segmentation fault

and call stack:

Process 16553 stopped
* thread #1, name = 'nmodl', stop reason = signal SIGSEGV: invalid address (fault address: 0x68)
    frame #0: 0x000000000085dd58 nmodl`std::__uniq_ptr_impl<llvm::ValueSymbolTable, std::default_delete<llvm::ValueSymbolTable> >::_M_ptr() const + 24
nmodl`std::__uniq_ptr_impl<llvm::ValueSymbolTable, std::default_delete<llvm::ValueSymbolTable> >::_M_ptr:
->  0x85dd58 <+24>: movq   (%rax), %rax
    0x85dd5b <+27>: leave
    0x85dd5c <+28>: retq
    0x85dd5d:       nop
(lldb) bt
* thread #1, name = 'nmodl', stop reason = signal SIGSEGV: invalid address (fault address: 0x68)
  * frame #0: 0x000000000085dd58 nmodl`std::__uniq_ptr_impl<llvm::ValueSymbolTable, std::default_delete<llvm::ValueSymbolTable> >::_M_ptr() const + 24
    frame #1: 0x000000000085c676 nmodl`std::unique_ptr<llvm::ValueSymbolTable, std::default_delete<llvm::ValueSymbolTable> >::get() const + 24
    frame #2: 0x0000000000859040 nmodl`llvm::Function::getValueSymbolTable() + 28
    frame #3: 0x00000000008538b8 nmodl`nmodl::codegen::CodegenLLVMVisitor::lookup(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) + 38
    frame #4: 0x0000000000856342 nmodl`nmodl::codegen::CodegenLLVMVisitor::visit_var_name(nmodl::ast::VarName const&) + 282
    frame #5: 0x000000000076d748 nmodl`nmodl::ast::VarName::accept(nmodl::visitor::ConstVisitor&) const + 46
    frame #6: 0x0000000000854812 nmodl`nmodl::codegen::CodegenLLVMVisitor::visit_binary_expression(nmodl::ast::BinaryExpression const&) + 92
    frame #7: 0x00000000007845e8 nmodl`nmodl::ast::BinaryExpression::accept(nmodl::visitor::ConstVisitor&) const + 48
    frame #8: 0x00000000007a6340 nmodl`nmodl::ast::WrappedExpression::visit_children(nmodl::visitor::ConstVisitor&) const + 54
    frame #9: 0x0000000000654008 nmodl`nmodl::visitor::ConstAstVisitor::visit_wrapped_expression(nmodl::ast::WrappedExpression const&) + 46
    frame #10: 0x00000000007a63a8 nmodl`nmodl::ast::WrappedExpression::accept(nmodl::visitor::ConstVisitor&) const + 48
    frame #11: 0x0000000000854812 nmodl`nmodl::codegen::CodegenLLVMVisitor::visit_binary_expression(nmodl::ast::BinaryExpression const&) + 92
    frame #12: 0x00000000007845e8 nmodl`nmodl::ast::BinaryExpression::accept(nmodl::visitor::ConstVisitor&) const + 48
    frame #13: 0x00000000007901ac nmodl`nmodl::ast::ExpressionStatement::visit_children(nmodl::visitor::ConstVisitor&) const + 54
    frame #14: 0x00000000006536da nmodl`nmodl::visitor::ConstAstVisitor::visit_expression_statement(nmodl::ast::ExpressionStatement const&) + 46
    frame #15: 0x0000000000790214 nmodl`nmodl::ast::ExpressionStatement::accept(nmodl::visitor::ConstVisitor&) const + 48
    frame #16: 0x0000000000854a69 nmodl`nmodl::codegen::CodegenLLVMVisitor::visit_statement_block(nmodl::ast::StatementBlock const&) + 169
    frame #17: 0x0000000000776446 nmodl`nmodl::ast::StatementBlock::accept(nmodl::visitor::ConstVisitor&) const + 48
    frame #18: 0x000000000077cbf6 nmodl`nmodl::ast::BreakpointBlock::visit_children(nmodl::visitor::ConstVisitor&) const + 54
    frame #19: 0x0000000000652dac nmodl`nmodl::visitor::ConstAstVisitor::visit_breakpoint_block(nmodl::ast::BreakpointBlock const&) + 46
    frame #20: 0x000000000077cc5e nmodl`nmodl::ast::BreakpointBlock::accept(nmodl::visitor::ConstVisitor&) const + 48
    frame #21: 0x00000000007a1d49 nmodl`nmodl::ast::Program::visit_children(nmodl::visitor::ConstVisitor&) const + 133
    frame #22: 0x0000000000855fae nmodl`nmodl::codegen::CodegenLLVMVisitor::visit_program(nmodl::ast::Program const&) + 310
    frame #23: 0x0000000000460b22 nmodl`main + 19159
    frame #24: 0x00007fffebc5c495 libc.so.6`__libc_start_main + 245
    frame #25: 0x000000000045bd27 nmodl`_start + 41
georgemitenkov commented 3 years ago

@pramodk This is fixed in the #533 :) The reason for this error is that code generation is done for the nodes inside functions, but some of the nodes outside were also visited. Hence, accessing a symbol table yielded a nullptr => segfault.