python-fastrpc 7+ SegFault
Closed this issue · 10 comments
Next code reproduces segmentation fault. Tested on versions 7.0.1
and 7.0.2
.
from fastrpc import ServerProxy
str(type(ServerProxy('http://sbox:2825/RPC2').bar))
GDB
backtrace
#0 _PyObject_Str (v=<unknown at remote 0x7ffff6c18e00>) at ../Objects/object.c:423
res = <optimized out>
type_ok = <optimized out>
#1 PyObject_Str (v=<unknown at remote 0x7ffff6c18e00>) at ../Objects/object.c:451
res = <type at remote 0x93cac0>
#2 string_new.lto_priv () at ../Objects/stringobject.c:3709
x = <unknown at remote 0x7ffff6c18e00>
kwlist = {0x6c8d61 "object", 0x0}
#3 0x00000000004ba865 in type_call.lto_priv () at ../Objects/typeobject.c:729
obj = <optimized out>
#4 0x00000000004caaa1 in PyObject_Call (kw=<optimized out>, arg=<optimized out>, func=<optimized out>) at ../Objects/abstract.c:2529
call = 0x4ba840 <type_call.lto_priv>
#5 do_call (nk=<optimized out>, na=<optimized out>, pp_stack=<optimized out>, func=<optimized out>) at ../Python/ceval.c:4251
callargs = (<unknown at remote 0x7ffff6c18e00>,)
kwdict = 0x0
#6 call_function (oparg=<optimized out>, pp_stack=<optimized out>) at ../Python/ceval.c:4056
func = <type at remote 0x93cac0>
w = <type at remote 0x93cac0>
nk = -135697328
n = -9552
pfunc = 0x7ffff7ef0c48
#7 PyEval_EvalFrameEx () at ../Python/ceval.c:2679
sp = 0x7ffff7ef0c50
opcode = 4958272
#8 0x00000000004c87a1 in PyEval_EvalCodeEx () at ../Python/ceval.c:3265
f = 0x0
retval = <code at remote 0x7ffff7ee2a30>
fastlocals = 0x4b3fa7 <vgetargskeywords.lto_priv+87>
tstate = 0x9ae0a0
u = <unknown at remote 0x1>
#9 0x00000000005030ef in PyEval_EvalCode (
locals={'__builtins__': <module at remote 0x7ffff7fa7b08>, '__file__': 'test.py', '__package__': None, '__name__': '__main__', 'ServerProxy': <built-in function ServerProxy>, '__doc__': None},
globals={'__builtins__': <module at remote 0x7ffff7fa7b08>, '__file__': 'test.py', '__package__': None, '__name__': '__main__', 'ServerProxy': <built-in function ServerProxy>, '__doc__': None},
co=0x7ffff7ee2a30) at ../Python/ceval.c:667
No locals.
#10 run_mod.lto_priv () at ../Python/pythonrun.c:1371
co = 0x7ffff7ee2a30
#11 0x00000000004f8c72 in PyRun_FileExFlags () at ../Python/pythonrun.c:1357
ret = <unknown at remote 0x7fffffffe66f>
mod = 0xa51508
arena = 0x9da5c0
#12 0x00000000004f7d77 in PyRun_SimpleFileExFlags () at ../Python/pythonrun.c:949
m = <module at remote 0x7ffff7f69cc8>
d = {'__builtins__': <module at remote 0x7ffff7fa7b08>, '__file__': 'test.py', '__package__': None, '__name__': '__main__', 'ServerProxy': <built-in function ServerProxy>, '__doc__': None}
v = <unknown at remote 0x1>
ret = -6542
#13 0x00000000004982f2 in Py_Main () at ../Modules/main.c:640
sts = 0
command = 0x0
filename = 0x7fffffffe66f "test.py"
stdin_is_interactive = 1
help = -135528320
version = 1
saw_unbuffered_flag = -6545
cf = {cf_flags = 0}
#14 0x00007ffff6f12b45 in __libc_start_main () from /lib/x86_64-linux-gnu/libc.so.6
No symbol table info available.
#15 0x0000000000497ca0 in _start ()
No symbol table info available.
Versions:
$ apt-cache policy python-fastrpc
python-fastrpc:
Installed: 7.0.2
Candidate: 7.0.2
Version table:
*** 7.0.2 0
470 http://debian/ jessie-stable/main amd64 Packages
460 http://debian/ jessie-testing/main amd64 Packages
150 /var/lib/dpkg/status
7.0.1 0
470 http://debian/ jessie-stable/main amd64 Packages
460 http://debian/ jessie-testing/main amd64 Packages
6.0.2~1 0
470 http://debian/ jessie-stable/main amd64 Packages
460 http://debian/ jessie-testing/main amd64 Packages
5.0.9 0
470 http://debian/ jessie-stable/main amd64 Packages
460 http://debian/ jessie-testing/main amd64 Packages
5.0.8 0
470 http://debian/ jessie-stable/main amd64 Packages
460 http://debian/ jessie-testing/main amd64 Packages
$ apt-cache policy libfastrpc7
libfastrpc7:
Installed: 7.0.1
Candidate: 7.0.1
Version table:
*** 7.0.1 0
470 http://debian/ jessie-stable/main amd64 Packages
460 http://debian/ jessie-testing/main amd64 Packages
150 /var/lib/dpkg/status
Same segfaults are in 6.0.2~1 and 5.1.0.
More info:
Program received signal SIGSEGV, Segmentation fault.
_PyObject_Str (v=<unknown at remote 0x7ffff6c18e00>) at ../Objects/object.c:423
423 ../Objects/object.c: No such file or directory.
(gdb) py-bt
#7 (<unknown at remote 0x7ffff6c18e00>,)
Python Exception <type 'exceptions.AttributeError'> 'PyTupleObjectPtr' object has no attribute 'current_line':
Error occurred in Python command: 'PyTupleObjectPtr' object has no attribute 'current_line'
I'm not an expert, but commit f050f93 seems suspicious. Mainly the use o Py_TPFLAGS_HAVE_GC
flag on static objects.
diff --git a/python/test/serverproxytest.py b/python/test/serverproxytest.py
index 16846f1..d2d1eb2 100755
--- a/python/test/serverproxytest.py
+++ b/python/test/serverproxytest.py
@@ -150,5 +150,10 @@ class ServerProxyTest(unittest.TestCase):
else:
self.assertIsInstance(client_hide_true.__dict__['last_call'], (str, unicode))
+ def test_reprstr(self):
+ client = fastrpc.ServerProxy(self.url)
+ self.assertTrue(str(type(client.foo)).startswith("<Method"))
+
+
if __name__ == '__main__':
unittest.main()
Okay, running with Py_DEBUG on python 2.7.11 reveals the init of frpc lib itself is broken
#0 0x00007ffff71422a8 in raise () from /usr/lib/libc.so.6
#1 0x00007ffff714372a in abort () from /usr/lib/libc.so.6
#2 0x0000000000508593 in Py_FatalError (msg=0x595756 "UNREF invalid object") at Python/pythonrun.c:1694
#3 0x0000000000463133 in _Py_ForgetReference (op=0x7ffff6cd35a0 <FRPC::Python::DateTimeObject_Type>) at Objects/object.c:2242
#4 0x0000000000463187 in _Py_Dealloc (op=0x7ffff6cd35a0 <FRPC::Python::DateTimeObject_Type>) at Objects/object.c:2261
#5 0x00000000004fffc8 in PyModule_AddObject (m=0x7ffff6f02dc8, name=0x7ffff6ac8c14 "DateTime", o=0x7ffff6cd35a0 <FRPC::Python::DateTimeObject_Type>) at Python/modsupport.c:618
#6 0x00007ffff6ab76a4 in initfastrpc () at fastrpcmodule.cc:2256
#7 0x00000000004f91a5 in _PyImport_LoadDynamicModule (name=0x8d7d20 "fastrpc", pathname=0x868740 "/home/volca/fastrpcmodule.so", fp=0x86d240) at ./Python/importdl.c:53
This will need to be fixed before continuing any further.
Edit: Apparently this is just a side-effect of Py_DEBUG and nothing to worry about.
Okay, I found the problem. It was caused by commit 30c9524, which replaced ob_type in type objects. Before, those referenced themselves. Now they have NULL ob_type, which causes python to segv when doing this "if (Py_TYPE(v)->tp_str == NULL)" on the type, since Py_TYPE returns ob_type of the object (which itself is the Type object).
I'll implement a patch tomorrow, it needs to be replaced on all custom types. Similary to this:
--- a/python/fastrpcmodule.cc
+++ b/python/fastrpcmodule.cc
@@ -1384,7 +1384,7 @@ extern "C"
static PyTypeObject Method_Type =
{
- PyVarObject_HEAD_INIT(NULL, 0)
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
@rembish Thanks, that needs a tweak though - the str(type(...)) will typically have the form of <type '...'>
. I'll modify that and patch it in.
Great job!
dpkg-buildpackage -rfakeroot -D -us -uc
dpkg-buildpackage: source package python-fastrpc
dpkg-buildpackage: source version 7.0.2-1
dpkg-buildpackage: source changed by Luboš Vondra <lubos.vondra@firma.seznam.cz>
dpkg-source --before-build python
dpkg-buildpackage: host architecture amd64
fakeroot debian/rules clean
dh clean --with=python2,python3 --buildsystem=pybuild
dh_testdir -O--buildsystem=pybuild
dh_auto_clean -O--buildsystem=pybuild
I: pybuild base:170: python2.7 setup.py clean
Traceback (most recent call last):
File "setup.py", line 30, in <module>
from fastrpc_version_info import version
ImportError: No module named fastrpc_version_info
E: pybuild pybuild:256: clean: plugin distutils failed with: exit code=1: python2.7 setup.py clean
dh_auto_clean: pybuild --clean -i python{version} -p 2.7 --dir . returned exit code 13
make: *** [clean] Error 13
dpkg-buildpackage: error: fakeroot debian/rules clean gave error exit status 2
debuild: fatal error at line 1357:
dpkg-buildpackage -rfakeroot -D -us -uc failed
Please reopen and fix building process.
I'll fix that, but it does not have anything to do with this particular bug.