Обсуждение: E_BAD_ACCESS with palloc/pfree in base type

Поиск
Список
Период
Сортировка

E_BAD_ACCESS with palloc/pfree in base type

От
Michael Glaesemann
Дата:
Hello all!

I'm working on a new base type. It's apparently installing fine via
PG_XS. I'm using malloc and free for memory management within the
module code.

x=# select '+1111'::x_type.x_type;
x_type
--------
+1111
(1 row)

x=# select '+111111111111'::x_type.x_type;
     x_type
---------------
+111111111111
(1 row)

It was recommended that I use palloc and pfree instead, so I replaced
malloc/free with palloc/pfree. However, now I'm getting E_BAD_ACCESS
errors (determined by stepping through the code with gdb) and
backends dying on me on input.

x=# select '+1111'::x_type.x_type;
x_type
--------
+1111
(1 row)

x=# select '+111111111111'::x_type.x_type;
server closed the connection unexpectedly
         This probably means the server terminated abnormally
         before or while processing the request.
The connection to the server was lost. Attempting reset: Failed.
!>

I suspect it's something straightforward as not only is this the
first base type I've worked on, I'm also not very experienced with C.
It was suggested that perhaps I'm having a problem as I'm not
defining a memory context. I thought that the memory context of the
calling code would be used by default. Is this the case? I've
included portions of the code below. I'd be happy to provide more
details if it would help.

Any ideas as to what's going on? Any comments or suggestions very
much appreciated.

Michael Glaesemann
grzm seespotcode net

--------------------------

--- x_type_base.c: X_TYPE_BASE_CHECK is not defined when compiling
with USE_PGXS

#ifndef X_TYPE_BASE_CHECK
#define free pfree
#define malloc palloc
#endif

/*
* xTypeFromString takes a string as its second argument and
* assigns to its first argument the XType value represented
* by the string. If the assignment is successful, xTypeFromString
* returns true, and false otherwise.
*/
static inline
XTypeParseResult xTypeFromString (XType * aNumber, char * aString)
{
     char * theDigits = malloc(sizeof(XTypeMaximumStringLength));
     XTypeCountryCode * countryCode = malloc(sizeof(XTypeCountryCode));
     char * subscriberNumber = malloc(XTypeMaximumStringLength);
     XTypeParseResult xTypeParseResult;

     xTypeParseResult = parseXTypeString(aString, theDigits,
                                       countryCode, subscriberNumber);
     free(subscriberNumber);
     if (XTypeNoParseError == xTypeParseResult)
     {
         XType xTypeResult;
         char *cp;
         initializeXTypeWithCountryCode(&xTypeResult, countryCode);
         xTypeResult = (xTypeResult | strtoll(theDigits, &cp, 10));
         *aNumber = xTypeResult;
     }
     free(countryCode);
     free(theDigits);
     return xTypeParseResult;
}

--- x_type.c includes x_type_base.c

#define DatumGetXTypeP(X) ((XType *) DatumGetPointer(X))
#define XTypePGetDatum(X) PointerGetDatum(X)
#define PG_GETARG_X_TYPE_P(X) DatumGetXTypeP(PG_GETARG_DATUM(X))
#define PG_RETURN_X_TYPE_P(X) return XTypePGetDatum(X)
#define PG_GETARG_X_TYPE(X) PG_GETARG_INT64((int64) X)
#define PG_RETURN_X_TYPE(X) PG_RETURN_INT64((int64) X)

PG_FUNCTION_INFO_V1(x_type_in);
Datum
x_type_in(PG_FUNCTION_ARGS)
{
     char * theString = PG_GETARG_CSTRING(0);
     XType theNumber;
     XTypeParseResult parseResult = xTypeFromString(&theNumber,
theString);
     if (XTypeNoParseError == parseResult)
     {
         XType * numberResult = palloc(sizeof(XType));
         *numberResult = theNumber;
         PG_RETURN_X_TYPE_P(numberResult);
     }
     else
         handleXTypeParseError(parseResult, theString);
}

PG_FUNCTION_INFO_V1(x_type_out);
Datum
x_type_out(PG_FUNCTION_ARGS)
{
     XType * theNumber = PG_GETARG_X_TYPE_P(0);
     char * theString = palloc(XTypeMaximumStringLength + 1);
     (void) stringFromXType(theString, theNumber,
XTypeMaximumStringLength);
     PG_RETURN_CSTRING(theString);
}



Re: E_BAD_ACCESS with palloc/pfree in base type

От
Gregory Stark
Дата:
"Michael Glaesemann" <grzm@seespotcode.net> writes:

>     char * theDigits = malloc(sizeof(XTypeMaximumStringLength));
...
>     char * subscriberNumber = malloc(XTypeMaximumStringLength);

One of those two is wrong, I suspect the first one. I wonder how you define
XTypeMaximumStringLength as sizeof(<integer constant>) ought to give a
compile-time error.

--
  Gregory Stark
  EnterpriseDB          http://www.enterprisedb.com

Re: E_BAD_ACCESS with palloc/pfree in base type

От
Michael Glaesemann
Дата:
On Aug 31, 2007, at 3:02 , Gregory Stark wrote:

> "Michael Glaesemann" <grzm@seespotcode.net> writes:
>
>>     char * theDigits = malloc(sizeof(XTypeMaximumStringLength));
> ...
>>     char * subscriberNumber = malloc(XTypeMaximumStringLength);
>
> One of those two is wrong, I suspect the first one.

Thanks, Greg. It looks like that was it. Always good to have a fresh
pair of eyes.

> I wonder how you define
> XTypeMaximumStringLength as sizeof(<integer constant>) ought to give a
> compile-time error.

It's an enum value. I do have a few compiler warnings (no errors)
left to clean up, but that doesn't appear to be one of them.

Thanks again for your help!

Michael Glaesemann
grzm seespotcode net