Это странное поведение, потому что я не мог не получить segfault
- если разделяемая библиотека была скомпилирована без или с более слабой оптимизацией (-O0 или -O1)
- если разделяемая библиотека была скомпилирована с помощью gcc, даже с флагом оптимизации (-O3)
- если бы я запускал код из программы на чистом C (не через ctypes)
Кроме того, я не мог получить segfault на некоторых машинах.
Если вы найдете ошибку в моем коде, это лучше, но у меня есть другие более общие вопросы:
- Это может быть ошибка icc или ctypes? Можно ли отправить ошибку в систему отслеживания проблем, даже если я могу воспроизвести странное поведение в моей конкретной среде?
- Я пытался отладить код, но, поскольку эта ошибка видна только тогда, когда код оптимизирован, я получил много "xxx определено, но не выделено (оптимизировано)" при использовании отладчика. Есть ли лучший способ отлаживать оптимизированный код?
Как воспроизвести баг
Предположим, у меня есть исходный код библиотеки странно.c и скрипт hte python run.py, я получаю segfault с:
icc -O3 -Wall -shared strange.c -o libstrange.so
python run.py
Обратите внимание, что я мог воспроизвести эту ошибку на одном из моих компьютеров.
uname -m
: i868- ОС: Ubuntu 10.04.2 LTS
- icc: 12.0.0 20101006
- Питон: 2.6.5
- Нампи: 1.3.0
но нет в
uname -m
: i868- ОС: Убунту 10.10
- icc: 12.0.3 20110309
- Питон: 2.6.6
- Нампи: 1.3.0
or
uname -m
: x86_64- ОС: Scientific Linux SL версии 5.5 (Boron)
- icc: 12.0.0 20101006
- Питон: 2.6.5
- Нампи: 1.5.0b1
Код
Набор кода можно найти здесь (tkf / ctypes_icc / source — Bitbucket) или ниже. Вы можете найти Makefile и сценарий оболочки для запуска программы и проверки кода выхода со всеми флагами оптимизации и компиляторами (gcc и icc). Первоначальная версия этой программы — программа моделирования для моих исследований, но эта программа — просто бессмысленная программа.
странно.с:
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;
}
запустить.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