Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TypeError: get_interpreter() returned NULL #82

Open
fishpepper opened this issue Aug 9, 2019 · 5 comments
Open

TypeError: get_interpreter() returned NULL #82

fishpepper opened this issue Aug 9, 2019 · 5 comments

Comments

@fishpepper
Copy link

Hi!

I am trying to build my own machinekit under a plain stretch based debian image.

I am struggling issues with getting the following error:

  File "/home/machinekit/src/machinekit/bin/axis", line 3215, in <module>
    o = MyOpengl(widgets.preview_frame, width=400, height=300, double=1, depth=1)
  File "/home/machinekit/src/machinekit/bin/axis", line 373, in __init__
    Opengl.__init__(self, *args, **kw)
  File "/home/machinekit/src/machinekit/lib/python/rs274/OpenGLTk.py", line 164, in __init__
    apply(RawOpengl.__init__, (self, master, cnf), kw)
  File "/home/machinekit/src/machinekit/lib/python/rs274/OpenGLTk.py", line 112, in __init__
    Togl.__init__(self, master, cnf, **kw)
  File "/home/machinekit/src/machinekit/lib/python/rs274/OpenGLTk.py", line 37, in __init__
    _togl.install(master.tk)
TypeError: get_interpreter() returned NULL
Exception AttributeError: "MyOpengl instance has no attribute '_dlists'" in <bound method MyOpengl.__del__ of <__main__.MyOpengl instance at 0xb4b11f08>> ignored
Shutting down and cleaning up Machinekit...

I traced it back to the file src/emc/usr_intf/axis/extensions/_toglmodule.c.
This diff adds some more debug info (might be good to have it in the master branch as well):

index 6c872b5fe..2a591566b 100644
--- a/src/emc/usr_intf/axis/extensions/_toglmodule.c
+++ b/src/emc/usr_intf/axis/extensions/_toglmodule.c
@@ -22,8 +22,12 @@ static Tcl_Interp *get_interpreter(PyObject *tkapp) {
     PyObject *interpaddrobj = PyObject_CallMethod(tkapp, "interpaddr", NULL);
     if(interpaddrobj == NULL) { return NULL; }
     interpaddr = PyInt_AsLong(interpaddrobj);
+    if (PyErr_Occurred()){ 
+        PyErr_PrintEx(0);
+       return NULL;
+    }
     Py_DECREF(interpaddrobj);
-    if(interpaddr == -1) { return NULL; }
+    if((interpaddr == -1) && PyErr_Occurred()) { return NULL; }
     return (Tcl_Interp*)interpaddr;
 }

The change with the checking of == -1 is necessary as the PyInt_AsLong documentation says just checking for -1 is not correct.
Anyway, that is not my issue.... Running this modified code gives me this error reason:
OverflowError: Python int too large to convert to C long

Really strange... I have no idea of the internals of PyInt_AsLong but as I was curious and I tried to replace it by:
interpaddr = PyInt_AsUnsignedLongLongMask(interpaddrobj);
With this fix axis starts up just fine and it looks like all is working as expected.
I am sure this is not the correct way of doing it.
Maybe a python guru can point me in the right direction?

Simon

@fishpepper
Copy link
Author

I think this might be related to that issue:
https://bugs.python.org/issue18909

(my stretch image runs python 2.7.13-2)

@fishpepper
Copy link
Author

fishpepper commented Aug 10, 2019

It seems like the tkapp interpaddr was changed to return a Long.
I am not sure why this only happens for me :-\

However this patch fixes it for me:

diff --git a/src/emc/usr_intf/axis/extensions/_toglmodule.c b/src/emc/usr_intf/axis/extensions/_toglmodule.c
index 6c872b5fe..b51b2b137 100644
--- a/src/emc/usr_intf/axis/extensions/_toglmodule.c
+++ b/src/emc/usr_intf/axis/extensions/_toglmodule.c
@@ -18,12 +18,15 @@
 static int first_time = 1;
 
 static Tcl_Interp *get_interpreter(PyObject *tkapp) {
-    long interpaddr;
+    void* interpaddr;
     PyObject *interpaddrobj = PyObject_CallMethod(tkapp, "interpaddr", NULL);
     if(interpaddrobj == NULL) { return NULL; }
-    interpaddr = PyInt_AsLong(interpaddrobj);
+    interpaddr = PyLong_AsVoidPtr(interpaddrobj); 
     Py_DECREF(interpaddrobj);
-    if(interpaddr == -1) { return NULL; }
+    if(PyErr_Occurred()) {
+        PyErr_PrintEx(0);
+        return NULL;
+    }
     return (Tcl_Interp*)interpaddr;
 }

@ArcEye
Copy link
Collaborator

ArcEye commented Aug 10, 2019

According to your post, you are trying to build on stretch running a defunct xenomai2 kernel.
What architecture has not AFAIR been divulged.

If this only happens then, I would be loathe to change the codebase for such a corner case.

@ArcEye
Copy link
Collaborator

ArcEye commented Aug 10, 2019

I have just cloned and built machinekit from scratch on Buster/sid (amd64) and run the Axis sim_mm on the title code without incident.
My python version is 2.7.16+ so I don't think something has radically changed in python certainly not at your version ( unless they messed it up and reverted in later versions ).

@fishpepper
Copy link
Author

I am building machinekit on a beagleboneblack using the armhf stretch image.

And you are right, I am wondering why this happens only for me..
Maybe the xenomai kernel is somehow changing the way my system allocates the memory.

Anyway, it seems that the python tkinter stuff was changed a very long time ago to return a Long based on a void pointer:
python/cpython@930c3c9

Casting it back by using PyLong_AsVoidPtr() seems to be plausible to me. Going the way from int to long and then casting the long back to the Tcl_Interp pointer seems over complicated.

However I still do not get why this does not throw an out of range error and the asLong function does... Both should be 32bits?!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants