zdzhaoyong / Svar

A Tiny Modern C++ Header Brings Unified Interface for Different Languages
Other
147 stars 17 forks source link

Segmentation fault when cpp function return type is std::optional<int> #11

Open xiaodaxia-2008 opened 2 years ago

xiaodaxia-2008 commented 2 years ago

Please check the follow module

#include "Rain.h"
#include <Svar/Svar.h>

std::optional<int> HowManyRain(int n)
{
    if (n <= 0)
    {
        return std::nullopt;
    }
    return n;
}

REGISTER_SVAR_MODULE(Rain)
{
    svar["__name__"] = "rain module";
    svar["__doc__"] = "Template svar module by zen";
    svar["HowManyRain"] = HowManyRain;
}

EXPORT_SVAR_INSTANCE

I could use it in c++, but when using in python, it causes segmentation fualt:

In [1]: import svar In [2]: rain = svar.load("./lib/libRain.so") In [3]: rain.HowManyRain(10) Out[3]: [1] 308484 segmentation fault (core dumped) ipython

zdzhaoyong commented 2 years ago

What enviroment are you using? I tried out your example with v3 branch on ubuntu 20.04 and it works fine: image

And one more thing, we do not suggest you to use optional, it is better to use Svar directly for optional return.

xiaodaxia-2008 commented 2 years ago

I tested on Deepin 20.5 with master branch. I'll test again with v3 branch

xiaodaxia-2008 commented 2 years ago

It could be related with ipython. When using outside of ipython, it succeeds.

test.py is

import svar
from IPython import embed
rain = svar.load("./build/lib/libRain.so")
res = rain.HowManyRain(0)
print(f"rain.HowManyRain(0): {res}")
embed()

The output is normal, but if I type res directly in ipython, it will cause a segmentation fault bug. Howerver, print(res) will not.

➜ python3 -u test.py rain.HowManyRain(0): <std::optional object at 0x7f3c12321948> Python 3.7.3 (default, Mar 9 2022, 03:38:16) Type 'copyright', 'credits' or 'license' for more information IPython 7.33.0 -- An enhanced Interactive Python. Type '?' for help. In [1]: print(res) <std::optional object at 0x7f3c12321948> In [2]: res Out[2]: [1] 32213 segmentation fault (core dumped) python3 -u test.py

The following is some debug info:

➜  TemplateProject gdb python3
GNU gdb (Uos 8.2.1.1-1+security) 8.2.1
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from python3...(no debugging symbols found)...done.
(gdb) r test.py
Starting program: /usr/bin/python3 /home/rvbust/Rvbust/Sources/TemplateProject/test.py
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[Detaching after fork from child process 33116]
rain.HowManyRain(0): <std::optional<int> object at 0x7ffff5b89948>
[New Thread 0x7ffff526f700 (LWP 33118)]
Python 3.7.3 (default, Mar  9 2022, 03:38:16) 
Type 'copyright', 'credits' or 'license' for more information
IPython 7.33.0 -- An enhanced Interactive Python. Type '?' for help.

[New Thread 0x7fffeffff700 (LWP 33119)]
In [1]: res
[Thread 0x7fffeffff700 (LWP 33119) exited]
Out[1]: 
Thread 1 "python3" received signal SIGSEGV, Segmentation fault.
0x000000000059876e in ?? ()
(gdb) bt
#0  0x000000000059876e in ?? ()
#1  0x00000000005aa595 in PyObject_Repr ()
#2  0x00000000005683de in ?? ()
#3  0x00000000005689a6 in ?? ()
#4  0x00000000004d7cd4 in _PyMethodDescr_FastCallKeywords ()
#5  0x0000000000551fe4 in _PyEval_EvalFrameDefault ()
#6  0x00000000005d7bdc in _PyFunction_FastCallKeywords ()
#7  0x000000000054e17e in _PyEval_EvalFrameDefault ()
#8  0x00000000005d7bdc in _PyFunction_FastCallKeywords ()
#9  0x000000000054e17e in _PyEval_EvalFrameDefault ()
#10 0x000000000054b792 in _PyEval_EvalCodeWithName ()
#11 0x00000000005d90de in _PyFunction_FastCallDict ()
#12 0x000000000054f3c2 in _PyEval_EvalFrameDefault ()
#13 0x000000000054b792 in _PyEval_EvalCodeWithName ()
#14 0x00000000005d90de in _PyFunction_FastCallDict ()
#15 0x000000000054f3c2 in _PyEval_EvalFrameDefault ()
#16 0x000000000054b792 in _PyEval_EvalCodeWithName ()
#17 0x00000000005d90de in _PyFunction_FastCallDict ()
--Type <RET> for more, q to quit, c to continue without paging--
#18 0x000000000058e55b in ?? ()
#19 0x00000000005d89fb in _PyObject_FastCallKeywords ()
#20 0x000000000054aea1 in ?? ()
#21 0x000000000054ee9f in _PyEval_EvalFrameDefault ()
#22 0x000000000054b792 in _PyEval_EvalCodeWithName ()
#23 0x00000000005d7ed2 in _PyFunction_FastCallKeywords ()
#24 0x000000000054e17e in _PyEval_EvalFrameDefault ()
#25 0x00000000005d7bdc in _PyFunction_FastCallKeywords ()
#26 0x000000000054e17e in _PyEval_EvalFrameDefault ()
#27 0x000000000054b792 in _PyEval_EvalCodeWithName ()
#28 0x00000000005d90de in _PyFunction_FastCallDict ()
#29 0x000000000058e55b in ?? ()
#30 0x00000000005da812 in ?? ()
#31 0x00000000005daaa9 in PyObject_CallFunctionObjArgs ()
#32 0x0000000000550e8b in _PyEval_EvalFrameDefault ()
#33 0x000000000054b792 in _PyEval_EvalCodeWithName ()
#34 0x0000000000558997 in ?? ()
#35 0x00000000005d7213 in _PyMethodDef_RawFastCallKeywords ()
--Type <RET> for more, q to quit, c to continue without paging--
#36 0x0000000000551da4 in _PyEval_EvalFrameDefault ()
#37 0x00000000004d3ae6 in ?? ()
#38 0x000000000054f4e2 in _PyEval_EvalFrameDefault ()
#39 0x00000000004d3ae6 in ?? ()
#40 0x000000000054f4e2 in _PyEval_EvalFrameDefault ()
#41 0x00000000004d3ae6 in ?? ()
#42 0x00000000004d7a61 in _PyMethodDescr_FastCallKeywords ()
#43 0x0000000000551fe4 in _PyEval_EvalFrameDefault ()
#44 0x00000000005d7bdc in _PyFunction_FastCallKeywords ()
#45 0x000000000054dfdc in _PyEval_EvalFrameDefault ()
#46 0x00000000005d7bdc in _PyFunction_FastCallKeywords ()
#47 0x000000000054e17e in _PyEval_EvalFrameDefault ()
#48 0x000000000054b792 in _PyEval_EvalCodeWithName ()
#49 0x00000000005d7ed2 in _PyFunction_FastCallKeywords ()
#50 0x000000000054acd0 in ?? ()
#51 0x000000000054ee9f in _PyEval_EvalFrameDefault ()
#52 0x000000000054b792 in _PyEval_EvalCodeWithName ()
#53 0x00000000005d7ed2 in _PyFunction_FastCallKeywords ()
--Type <RET> for more, q to quit, c to continue without paging--
#54 0x000000000054e17e in _PyEval_EvalFrameDefault ()
#55 0x000000000054b792 in _PyEval_EvalCodeWithName ()
#56 0x00000000005d7ed2 in _PyFunction_FastCallKeywords ()
#57 0x000000000054acd0 in ?? ()
#58 0x000000000054ee9f in _PyEval_EvalFrameDefault ()
#59 0x000000000054b792 in _PyEval_EvalCodeWithName ()
#60 0x00000000005d90de in _PyFunction_FastCallDict ()
#61 0x000000000058e55b in ?? ()
#62 0x00000000005d89fb in _PyObject_FastCallKeywords ()
#63 0x000000000054aea1 in ?? ()
#64 0x000000000054ee9f in _PyEval_EvalFrameDefault ()
#65 0x000000000054b792 in _PyEval_EvalCodeWithName ()
#66 0x00000000005d7ed2 in _PyFunction_FastCallKeywords ()
#67 0x000000000054dfdc in _PyEval_EvalFrameDefault ()
#68 0x000000000054b792 in _PyEval_EvalCodeWithName ()
#69 0x000000000054dad3 in PyEval_EvalCode ()
#70 0x000000000062fe62 in ?? ()
#71 0x000000000062ff17 in PyRun_FileExFlags ()
--Type <RET> for more, q to quit, c to continue without paging--
#72 0x0000000000630b7f in PyRun_SimpleFileExFlags ()
#73 0x00000000006538ee in ?? ()
#74 0x0000000000653c4e in _Py_UnixMain ()
#75 0x00007ffff7baa09b in __libc_start_main (main=0x4bc730 <main>, argc=2, argv=0x7fffffffdb88, init=<optimized out>, fini=<optimized out>, 
    rtld_fini=<optimized out>, stack_end=0x7fffffffdb78) at ../csu/libc-start.c:308
#76 0x00000000005df87a in _start ()