4

セグメンテーション違反を取得できなかったため、この動作は奇妙です

  • 共有ライブラリが最適化なしまたは最適化なしでコンパイルされた場合(-O0または-O1)
  • 共有ライブラリがgccでコンパイルされた場合、最適化フラグ(-O3)を使用しても
  • 純粋なCプログラムから(ctypes経由ではなく)コードを実行した場合

さらに、一部のマシンでセグメンテーション違反を取得できませんでした。

私のコードにバグを見つけた場合、それはより良いですが、他のより一般的な質問があります:

  1. それはiccまたはctypesのバグである可能性がありますか?特定の環境で奇妙な動作を再現できたとしても、バグを提出して追跡システムを発行しても大丈夫ですか?
  2. コードをデバッグしようとしましたが、このバグはコードが最適化されている場合にのみ表示されるため、デバッガーを使用すると「xxxは定義されていますが、割り当てられていません(最適化されていない)」というメッセージがたくさん表示されます。最適化されたコードをデバッグするためのより良い方法はありますか?

バグを再現する方法

ライブラリのソースコードstrange.cとhtepythonスクリプトrun.pyがあるとすると、次のようなセグメンテーション違反が発生します。

icc -O3 -Wall -shared strange.c -o libstrange.so
python run.py

私のマシンの1つでこのバグを再現できることに注意してください

  • uname -m:i868
  • OS:Ubuntu 10.04.2 LTS
  • icc:12.0.0 20101006
  • Python:2.6.5
  • ゴツゴツ:1.3.0

しかし、ではありません

  • uname -m:i868
  • OS:Ubuntu 10.10
  • icc:12.0.3 20110309
  • Python:2.6.6
  • ゴツゴツ:1.3.0

また

  • uname -m:x86_64
  • OS:Scientific Linux SLリリース5.5(Boron)
  • icc:12.0.0 20101006
  • Python:2.6.5
  • ゴツゴツ:1.5.0b1

コード

ここ(tkf / ctypes_icc / source – Bitbucket)または以下のコードセットを見つけてください。プログラムを実行し、すべての最適化フラグとコンパイラー(gccおよびicc)を使用して終了コードを確認するためのMakefileとシェルスクリプトを見つけることができます。このプログラムの元のバージョンは私の研究のためのシミュレーションプログラムですが、このプログラムは単なる無意味なプログラムです。

奇妙な.c:

typedef struct{
  int num_n;
  double dt, ie, gl, isyn, ssyn, tau1, tau2, lmd1, lmd2, k1_mean, k2_mean;
  double *vi, *v0;
} StrangeStruct;


void
func(double * v0, double * vt, double dt,
     double gl, double isyn, double ie, double isyn_estimate, int num_n)
{
  int i;
  for (i = 0; i < num_n; ++i){
    v0[i] = vt[i] + dt + gl + isyn + ie + isyn_estimate;
  }
}

int
StrangeStruct_func(StrangeStruct *self)
{
  double isyn_estimate;
  isyn_estimate =
    self->ssyn * (self->lmd1 * self->k1_mean - self->lmd2 * self->k2_mean) /
    (self->tau1 - self->tau2);
  func(self->v0, self->vi, self->dt, self->gl, self->isyn,
       self->ie, isyn_estimate, self->num_n);
  return 0;
}

run.py:

from ctypes import POINTER, pointer, c_int, c_double, Structure
import numpy

c_double_p = POINTER(c_double)


class StrangeStruct(Structure):
    _fields_ = [
        ("num_n", c_int),
        ("dt", c_double),
        ("ie", c_double),
        ("gl", c_double),
        ("isyn", c_double),
        ("ssyn", c_double),
        ("tau1", c_double),
        ("tau2", c_double),
        ("lmd1", c_double),
        ("lmd2", c_double),
        ("k1_mean", c_double),
        ("k2_mean", c_double),
        ("vi", c_double_p),
        ("v0", c_double_p),
        ]


StrangeStruct_p = POINTER(StrangeStruct)

ifnet_a2a2 = numpy.ctypeslib.load_library('libstrange.so', '.')
ifnet_a2a2.StrangeStruct_func.restype = c_int
ifnet_a2a2.StrangeStruct_func.argtypes = [StrangeStruct_p]


def func(struct):
    ifnet_a2a2.StrangeStruct_func(pointer(struct))


if __name__ == '__main__':
    ifn = StrangeStruct(
        num_n=100, dt=0.1, gl=0.1, vrest=-60, ie=-3.7, th=-40,
        ssyn=0.5, tau1=3, tau2=1,
        )
    v0 = numpy.zeros(ifn.num_n, dtype=float)
    vi = numpy.zeros(ifn.num_n, dtype=float)
    ifn.v0 = v0.ctypes.data_as(c_double_p)
    ifn.vi = vi.ctypes.data_as(c_double_p)

    func(ifn)

    v0 + vi
4

1 に答える 1

3

通常、gccとiccでコンパイルされたバイナリを混在させることはできません(この場合、Pythonはgccでビルドされます)。-gcc-versionフラグで設定されるiccの「gcc互換」モードを使用してみることができます。それでうまくいくかもしれませんが、それでも問題が発生する可能性があります。

于 2011-04-27T19:34:34.543 に答える