[pypy-issue] Issue #2430: Use of print via embedded code crashes python (pypy/pypy)
Whitney Young
issues-reply at bitbucket.org
Mon Nov 7 20:36:29 EST 2016
New issue 2430: Use of print via embedded code crashes python
https://bitbucket.org/pypy/pypy/issues/2430/use-of-print-via-embedded-code-crashes
Whitney Young:
I have issues trying to use `print` both when [embedding PyPy via CFFI](http://cffi.readthedocs.io/en/latest/embedding.html) and when using the [legacy embedding approach](http://doc.pypy.org/en/latest/embedding.html).
**CFFI**
I've taken the vanilla [embedding code](http://cffi.readthedocs.io/en/latest/embedding.html#usage) and modified it slightly to try to trace the error:
```c
/* file plugin.h */
typedef struct { int x, y; } point_t;
extern int do_stuff(point_t *);
```
```python
# file plugin_build.py
import cffi
ffibuilder = cffi.FFI()
with open('plugin.h') as f:
ffibuilder.embedding_api(f.read())
ffibuilder.set_source("my_plugin", '''
#include "plugin.h"
''')
ffibuilder.embedding_init_code(r"""
from my_plugin import ffi
@ffi.def_extern()
def do_stuff(p):
import sys
with open("/tmp/out", "a") as f:
f.write("running embedded\n")
sys.stderr.write(b"stderr works\n")
sys.stdout.write(b"stdout works\n")
try:
print("print is broken\n")
except Exception as e:
f.write("exception\n")
f.write(repr(e) + " " + str(e) + "\n")
sys.stderr.write(bytes(repr(e) + "\n", encoding="utf8"))
print("adding %d and %d" % (p.x, p.y))
return p.x + p.y
""")
ffibuilder.compile(target="plugin-1.5.*", verbose=True)
```
Compilation of this is like so for me:
```
$ python plugin.py
python: /home/wyoung/.linuxbrew/lib/libssl.so.1.0.0: no version information available (required by /home/wyoung/dev/api/env/bin/libpypy-c.so)
python: /home/wyoung/.linuxbrew/lib/libssl.so.1.0.0: no version information available (required by /home/wyoung/dev/api/env/bin/libpypy-c.so)
python: /home/wyoung/.linuxbrew/lib/libcrypto.so.1.0.0: no version information available (required by /home/wyoung/dev/api/env/bin/libpypy-c.so)
generating ./my_plugin.c
running build_ext
building 'my_plugin' extension
cc -O2 -fPIC -Wimplicit -I/home/wyoung/dev/api/env/include -c my_plugin.c -o ./my_plugin.o
my_plugin.c:825:5: warning: initialization from incompatible pointer type [enabled by default]
_CFFI_PYTHON_STARTUP_FUNC,
^
my_plugin.c:825:5: warning: (near initialization for ‘_cffi_pypy_init.func’) [enabled by default]
cc -shared ./my_plugin.o -L/home/wyoung/dev/api/env/bin -L/home/wyoung/dev/api/env/pypy/goal -lpypy-c -o ./plugin-1.5.so
```
I have a small driver program, `test.c` that I'm using to load this:
```c
#define _GNU_SOURCE
#include "plugin.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
int main() {
void *handle;
handle = dlopen("/home/wyoung/.pythons/pypy3-v5.5.0-linux64/bin/libpypy-c.so", RTLD_NOW | RTLD_GLOBAL);
if (!handle) {
printf("cant find libpypy\n");
exit(1);
}
handle = dlopen("/home/wyoung/dev/api/plugin-1.5.so", RTLD_NOW | RTLD_GLOBAL);
if (!handle) {
printf("could not load plugin :(\n");
}
point_t the_point;
the_point.x = 12;
the_point.y = 14;
int (*stuff)(point_t *) = dlsym(handle, "do_stuff");
int res = stuff(&the_point);
printf("res is %d through function at %p\n", res, stuff);
return 0;
}
```
When compiled & run:
```
$ gcc test.c -o test -ldl && LD_LIBRARY_PATH="/home/wyoung/.pythons/pypy3-v5.5.0-linux64/bin:$LD_LIBRARY_PATH" ./test
stderr works
stdout works
TypeError('must be bytes or buffer, not str',)
res is 0 through 0x7f4d9ef7dcc0
```
**Legacy Approach**
I get the same error as [described on this uWSGI issue](https://github.com/unbit/uwsgi/issues/869#issue-61051504):
```
debug: OperationError:
debug: operror-type: AttributeError
debug: operror-value: 'module' object has no attribute 'stdout'
```
I would imagine this is related to the above issue.
More information about the pypy-issue
mailing list