Skip to content

segfault when overriding a class method in jupyter kernel #64

@sigmaSd

Description

@sigmaSd

To reproduce

pip install ipykernel

a.ts

#!/usr/bin/env -S deno run --allow-all --allow-ffi --allow-env=DENO_PYTHON_PATH --unstable-ffi
import { NamedArgument, PyObject, python } from "jsr:@denosaurs/python";

const Kernel = python.import("ipykernel.kernelbase").Kernel;

class RKernel extends Kernel {
}

const p = PyObject.from(RKernel);
p.setAttr("implementation", "R");
p.setAttr("implementation_version", "1.0");
p.setAttr("language", "rust");
p.setAttr("language_version", "1");
p.setAttr("language_info", {
  name: "R",
  mimetype: "text/x-rust",
  file_extension: ".rs",
});
p.setAttr("banner", "R");
p.setAttr("kernel_name", "irust");

// Commenting this out, fixes the segfault
p.setAttr(
  "do_execute",`
  python.callback(() => {
  }),
);

if (import.meta.main) {
  const IPKernelApp = python.import("ipykernel.kernelapp").IPKernelApp;
  IPKernelApp.launch_instance(new NamedArgument("kernel_class", p));
}

chmod +x && ./a.ts

I followed with gdb

#0  0x00007ffff7e1dfb0 in __strncmp_sse42 () from /lib64/libc.so.6
#1  0x00007ffff4bf79f1 in find_signature () from /lib64/libpython3.12.so
#2  0x00007ffff4c79c70 in _PyType_GetTextSignatureFromInternalDoc ()
   from /lib64/libpython3.12.so
#3  0x00007ffff4b8fedd in _PyObject_GenericGetAttrWithDict ()
   from /lib64/libpython3.12.so
#4  0x00007ffff4b89be5 in _PyObject_LookupAttr ()
   from /lib64/libpython3.12.so
#5  0x00007ffff4b9215f in builtin_getattr () from /lib64/libpython3.12.so
#6  0x00007ffff4b91ba2 in cfunction_vectorcall_FASTCALL ()
   from /lib64/libpython3.12.so
#7  0x00007ffff4b88b7c in PyObject_Vectorcall ()
   from /lib64/libpython3.12.so
#8  0x00007ffff4b71ea5 in _PyEval_EvalFrameDefault ()
   from /lib64/libpython3.12.so
#9  0x00007ffff4b6bcbb in _PyObject_FastCallDictTstate ()
   from /lib64/libpython3.12.so
#10 0x00007ffff4b9ad04 in slot_tp_init () from /lib64/libpython3.12.so
#11 0x00007ffff4b696cb in type_call () from /lib64/libpython3.12.so
#12 0x00007ffff4b9e049 in _PyObject_Call () from /lib64/libpython3.12.so
#13 0x00007ffff4b76e45 in _PyEval_EvalFrameDefault ()
   from /lib64/libpython3.12.so
#14 0x00007ffff4bb0738 in method_vectorcall ()
   from /lib64/libpython3.12.so
#15 0x00007ffff4b9e145 in _PyVectorcall_Call ()
   from /lib64/libpython3.12.so
#16 0x00005555580bf052 in ffi_call_unix64 ()
#17 0x000055555adfbb27 in ffi_call_int.llvm ()
#18 0x000055555adfb89f in ffi_call ()
#19 0x000055555adce43f in <extern "C" fn(A0) .> R as v8::support::CFnFrom<F>>::mapping::c_fn ()
#20 0x000055555952d6df in Builtins_CallApiCallbackGeneric ()

If I check what its comparing, its comparing the function name to the function docs, but the function docs are an invalid pointer

(gdb) info registers
rax            0x15                21
rbx            0x55555c661e40      93825110777408
rcx            0x0                 0
rdx            0x14                20
rsi            0x55555c661e40      93825110777408
rdi            0x5555              21845
rbp            0x7ffffffeabd0      0x7ffffffeabd0
rsp            0x7ffffffeaba8      0x7ffffffeaba8
r8             0xfcfe              64766
r9             0x7ffff72481e0      140737339752928
r10            0xd                 13
r11            0x14                20
r12            0x5555              21845
r13            0x14                20
r14            0x0                 0
r15            0x7ffff4f55f80      140737303109504
rip            0x7ffff7e1dfb0      0x7ffff7e1dfb0 <__strncmp_sse42+48>
eflags         0x10283             [ CF SF IF RF ]
cs             0x33                51
ss             0x2b                43
ds             0x0                 0
es             0x0                 0
fs             0x0                 0
gs             0x0                 0
fs_base        0x7ffff7c8c480      140737350517888
gs_base        0x0                 0
(gdb) x/s 0x55555c661e40
0x55555c661e40: "JSCallback:anonymous"

rdi register have an invalid pointer

The 2 (name and doc) should come from the same buffer which is this one https://github.com/denosaurs/deno_python/blob/main/src/python.ts#L479 docs: https://docs.python.org/3/c-api/structures.html#c.PyMethodDef

I also inspected that buffer when the segfault happened, and it seemed correct

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions