Я написал библиотеку расширения C для PG, используя соглашение о вызовах V1.Когда я вызываю агрегатную функцию, происходит сбой процесса на сервере postgres.Я использовал gdb для отладки серверного процесса и обнаружил, где происходит Seg-V.
Это вызвано попыткой доступа к неверному адресу.что я не понимаю, так это то, что память была успешно распределена ранее.Судя по комментарию в коде, я подозреваю, что память собирается / освобождается, пока она еще используется.Я не знаю достаточно о внутренностях postgres - но это кажется вероятной причиной проблемы.
Я включил код для функции, которая вызывает сбой, и выделил строку, которая вызывает Seg-V,Я вызываю MemoryContextAlloc с правильными параметрами?
static PGARRAY *GetPGArray(int4 state, int fAdd);
static PGARRAY *ShrinkPGArray(PGARRAY * p);
Datum float8_agg_state(PG_FUNCTION_ARGS);
Datum float8_agg_final_count(PG_FUNCTION_ARGS);
Datum float8_agg_final_array(PG_FUNCTION_ARGS);
Datum float8_enum(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(float8_agg_state);
PG_FUNCTION_INFO_V1(float8_agg_final_count);
PG_FUNCTION_INFO_V1(float8_agg_final_array);
PG_FUNCTION_INFO_V1(float8_enum);
/*
* Manage the aggregation state of the array
*
* Need to specify a suitably long-lived memory context, or it will vanish!
* PortalContext isn't really right, but it's close enough (famous last words ...).
*/
static PGARRAY *
GetPGArray(int4 state, int fAdd)
{
PGARRAY *p = (PGARRAY *) state;
if (!state)
{
/* New array */
int cb = PGARRAY_SIZE(START_NUM);
p = (PGARRAY *) MemoryContextAlloc(PortalContext, cb);
p->a.vl_len_ = cb;
p->a.ndim = 0;
p->a.dataoffset = 0;
#ifndef PG_7_2
p->a.elemtype = FLOAT8OID;
#endif
p->items = 0;
p->lower = START_NUM;
}
else if (fAdd)
{
/* Ensure array has space */
/* SEG-V fault on the line below */
if (p->items >= p->lower)
{
PGARRAY *pn;
int n = p->lower + p->lower;
int cbNew = PGARRAY_SIZE(n);
pn = (PGARRAY *) repalloc(p, cbNew);
pn->a.vl_len_ = cbNew;
pn->lower = n;
return pn;
}
}
return p;
}
Может кто-нибудь определить, почему код SG-V?
[[Редактировать]]
Мой внутренний PG-сервер v8.4.9