4

C ++のPython拡張機能で奇妙な問題が発生しています。助けや提案をいただければ幸いです。

コンテキストを設定します。

C++ に埋め込まれた python を使用して、python スクリプトを実行しています。また、C++ で Python 拡張機能を使用して、Python スクリプトが C++ 関数を呼び出すことができるようにしています。

問題は何ですか?

  1. 以下に示すように、モジュール「メソッドテーブル」からメソッドエントリにコメントすると。アプリケーションがクラッシュしたり、セグメンテーション違反がまったく発生したりしません。

    static PyMethodDef sa_methods[] = {
    
    //{"GetBlue",(PyCFunction)sa_GetBlue,METH_VARARGS,PyDoc_STR("fetches Blue color")},
    
    //{"GetRed",(PyCFunction)sa_GetRed,METH_VARARGS,PyDoc_STR("fetches Red color")},
    
    {"GetYellow",(PyCFunction)sa_GetYellow,METH_VARARGS,PyDoc_STR("fetches yellow color")},                        
    
    {"GetPink",(PyCFunction)sa_GetPink,METH_VARARGS,PyDoc_STR("fetches pink color")},
    
    {NULL, NULL, 0, NULL}
    
    };
    
  2. 以下に示すように、モジュール「メソッドテーブル」のメソッドエントリからメソッドコメントを削除すると。アプリケーションは、20000 から 50000 のリクエストをランダムに処理する間に常にクラッシュします。

    static PyMethodDef sa_methods[] = {
    
    {"GetBlue",(PyCFunction)sa_GetBlue,METH_VARARGS,PyDoc_STR("fetches Blue color")},
    
    {"GetRed",(PyCFunction)sa_GetRed,METH_VARARGS,PyDoc_STR("fetches Red color")},
    
    {"GetYellow",(PyCFunction)sa_GetYellow,METH_VARARGS,PyDoc_STR("fetches yellow color")},                        
    
    {"GetPink",(PyCFunction)sa_GetPink,METH_VARARGS,PyDoc_STR("fetches pink color")},
    
    {NULL, NULL, 0, NULL}
    
    };
    

上記の 2 つのメソッドを空のままにして、単に Py_False を返すだけです。

毎回取得しているスタック トレースの下を見つけてください。

#0  0x00002b700146c4d7 in PyNumber_CoerceEx (pv=0x41801798, pw=0x41801790) at Objects/object.c:1599
#1  0x00002b700142d6e3 in binary_op1 (v=0x2aaaac079600, w=0x2b7001750550, op_slot=16) at Objects/abstract.c:929
#2  0x00002b7001431e08 in PyNumber_Multiply (v=0x41801798, w=0x41801790) at Objects/abstract.c:1188
#3  0x00002b70014c4326 in PyEval_EvalFrameEx (f=0x8127780, throwflag=<value optimized out>) at Python/ceval.c:1118
#4  0x00002b70014c8493 in call_function (f=0x996e660, throwflag=<value optimized out>) at Python/ceval.c:3792
#5  PyEval_EvalFrameEx (f=0x996e660, throwflag=<value optimized out>) at Python/ceval.c:2389
#6  0x00002b70014c8493 in call_function (f=0x2aaac30aeb50, throwflag=<value optimized out>) at Python/ceval.c:3792
#7  PyEval_EvalFrameEx (f=0x2aaac30aeb50, throwflag=<value optimized out>) at Python/ceval.c:2389
#8  0x00002b70014c8d9f in PyEval_EvalCodeEx (co=0x2aaaad7dc558, globals=<value optimized out>, locals=<value optimized out>, args=0x2aaac6ab59a0, argcount=2,
    kws=0x2aaac6ab59b0, kwcount=0, defs=0x7819128, defcount=1, closure=0x0) at Python/ceval.c:2968
#9  0x00002b70014c6df3 in call_function (f=0x2aaac6ab57d0, throwflag=<value optimized out>) at Python/ceval.c:3802
#10 PyEval_EvalFrameEx (f=0x2aaac6ab57d0, throwflag=<value optimized out>) at Python/ceval.c:2389
#11 0x00002b70014c8d9f in PyEval_EvalCodeEx (co=0x2aaabdf8e828, globals=<value optimized out>, locals=<value optimized out>, args=0x2aaac65bcbf0, argcount=2,
    kws=0x2aaac65bcc00, kwcount=0, defs=0x7819c28, defcount=1, closure=0x0) at Python/ceval.c:2968
#12 0x00002b70014c6df3 in call_function (f=0x2aaac65bca40, throwflag=<value optimized out>) at Python/ceval.c:3802
#13 PyEval_EvalFrameEx (f=0x2aaac65bca40, throwflag=<value optimized out>) at Python/ceval.c:2389
#14 0x00002b70014c8493 in call_function (f=0x2aaac6301630, throwflag=<value optimized out>) at Python/ceval.c:3792
#15 PyEval_EvalFrameEx (f=0x2aaac6301630, throwflag=<value optimized out>) at Python/ceval.c:2389
#16 0x00002b70014c8d9f in PyEval_EvalCodeEx (co=0x6c7f558, globals=<value optimized out>, locals=<value optimized out>, args=0x2aaac55963e8, argcount=2,
    kws=0x2aaac55963f8, kwcount=0, defs=0xd83fce8, defcount=1, closure=0x0) at Python/ceval.c:2968
#17 0x00002b70014c6df3 in call_function (f=0x2aaac5596240, throwflag=<value optimized out>) at Python/ceval.c:3802
#18 PyEval_EvalFrameEx (f=0x2aaac5596240, throwflag=<value optimized out>) at Python/ceval.c:2389
#19 0x00002b70014c8d9f in PyEval_EvalCodeEx (co=0x6c7fcd8, globals=<value optimized out>, locals=<value optimized out>, args=0x2aaac6fbc328, argcount=2,
    kws=0x2aaac6fbc338, kwcount=0, defs=0xd83fc68, defcount=1, closure=0x0) at Python/ceval.c:2968
#20 0x00002b70014c6df3 in call_function (f=0x2aaac6fbc1a0, throwflag=<value optimized out>) at Python/ceval.c:3802
#21 PyEval_EvalFrameEx (f=0x2aaac6fbc1a0, throwflag=<value optimized out>) at Python/ceval.c:2389
#22 0x00002b70014c8d9f in PyEval_EvalCodeEx (co=0x6c7f648, globals=<value optimized out>, locals=<value optimized out>, args=0x1, argcount=0, kws=0x2aaac3e32558,
    kwcount=0, defs=0xd83ffa8, defcount=1, closure=0x0) at Python/ceval.c:2968
#23 0x00002b70014c6df3 in call_function (f=0x2aaac3e323d0, throwflag=<value optimized out>) at Python/ceval.c:3802
#24 PyEval_EvalFrameEx (f=0x2aaac3e323d0, throwflag=<value optimized out>) at Python/ceval.c:2389
#25 0x00002b70014c8d9f in PyEval_EvalCodeEx (co=0x2aaaad7f70a8, globals=<value optimized out>, locals=<value optimized out>, args=0x0, argcount=0, kws=0x1325c6a8,
    kwcount=0, defs=0x0, defcount=0, closure=0x2aaaad18e990) at Python/ceval.c:2968
#26 0x00002b70014c6df3 in call_function (f=0x1325c480, throwflag=<value optimized out>) at Python/ceval.c:3802
#27 PyEval_EvalFrameEx (f=0x1325c480, throwflag=<value optimized out>) at Python/ceval.c:2389
#28 0x00002b70014c8d9f in PyEval_EvalCodeEx (co=0x2aaaad7f77b0, globals=<value optimized out>, locals=<value optimized out>, args=0x1, argcount=1, kws=0x2aaac5ec1d08,
    kwcount=0, defs=0x2aaaacfdf5e8, defcount=1, closure=0x0) at Python/ceval.c:2968
#29 0x00002b70014c6df3 in call_function (f=0x2aaac5ec1b00, throwflag=<value optimized out>) at Python/ceval.c:3802
#30 PyEval_EvalFrameEx (f=0x2aaac5ec1b00, throwflag=<value optimized out>) at Python/ceval.c:2389
#31 0x00002b70014c8493 in call_function (f=0xa926080, throwflag=<value optimized out>) at Python/ceval.c:3792
#32 PyEval_EvalFrameEx (f=0xa926080, throwflag=<value optimized out>) at Python/ceval.c:2389
#33 0x00002b70014c8493 in call_function (f=0x8e4bd40, throwflag=<value optimized out>) at Python/ceval.c:3792
#34 PyEval_EvalFrameEx (f=0x8e4bd40, throwflag=<value optimized out>) at Python/ceval.c:2389
#35 0x00002b70014c8d9f in PyEval_EvalCodeEx (co=0x2aaabc9f7648, globals=<value optimized out>, locals=<value optimized out>, args=0x9ff5f58, argcount=1,
---Type <return> to continue, or q <return> to quit---
    kws=0x9ff5f60, kwcount=0, defs=0x0, defcount=0, closure=0x2aaaacfdfc50) at Python/ceval.c:2968
#36 0x00002b70014c6df3 in call_function (f=0x9ff5dc0, throwflag=<value optimized out>) at Python/ceval.c:3802
#37 PyEval_EvalFrameEx (f=0x9ff5dc0, throwflag=<value optimized out>) at Python/ceval.c:2389
#38 0x00002b70014c8493 in call_function (f=0xdb993e0, throwflag=<value optimized out>) at Python/ceval.c:3792
#39 PyEval_EvalFrameEx (f=0xdb993e0, throwflag=<value optimized out>) at Python/ceval.c:2389
#40 0x00002b70014c8d9f in PyEval_EvalCodeEx (co=0x2aaabd820990, globals=<value optimized out>, locals=<value optimized out>, args=0x2aaaacfdf8a8, argcount=1, kws=0x0,
    kwcount=0, defs=0x0, defcount=0, closure=0x0) at Python/ceval.c:2968
#41 0x00002b700145815d in function_call (func=0x7d898c0, arg=0x2aaaacfdf890, kw=0x0) at Objects/funcobject.c:524
#42 0x00002b700142d318 in PyObject_Call (func=0x7d898c0, arg=0x2aaaacfdf890, kw=0x0) at Objects/abstract.c:2492
#43 0x00002b700143cd7f in instancemethod_call (func=<value optimized out>, arg=0x2aaaacfdf890, kw=0x0) at Objects/classobject.c:2579
#44 0x00002b700142d318 in PyObject_Call (func=0x7554690, arg=0x2aaaac04d050, kw=0x0) at Objects/abstract.c:2492
#45 0x00002b70014c0e16 in PyEval_CallObjectWithKeywords (func=0x7554690, arg=0x2aaaac04d050, kw=0x0) at Python/ceval.c:3575
#46 0x00002b70014f9dcd in t_bootstrap (boot_raw=0x2aaac76e67c0) at ./Modules/threadmodule.c:425
#47 0x00000033c720677d in start_thread () from /lib64/libpthread.so.0
#48 0x00000033c66d33ed in clone () from /lib64/libc.so.6
4

1 に答える 1

5

私はこの問題の解決策を手に入れました。それは最終的に私と私のクライアントに大きな安心をもたらしました。

そして、ここに理由と解決策があります。

関数「sa_GetBlue」と「sa_GetRed」は「Py_False」を返していました。「Py_False」または「Py_True」を返す前に、これらの値を保持する変数の参照カウントを増やす必要があります。そうしないと、インタープリターのメモリ状態が破損する可能性があります。すぐにはクラッシュしませんが、いつでもクラッシュする可能性があります。私の場合、20000から50000のリクエストを処理した後、クラッシュしていました。

私が説明しようとしていることについてのより多くのアイデアを得るために、以下のリンクをチェックしてください。

why-does-python-keep-a-reference-count-on-false-and-true

@doomsterと@Omnifarious; あなたが提供したコメントと方向性をありがとう。

于 2013-02-20T09:09:09.720 に答える