Обсуждение: custom C function problem

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

custom C function problem

От
"Dan \"Heron\" Myers"
Дата:
I'm creating some custom C functions to load dynamically from a dll
(this is Postgres 8.3.1 on Windows XP SP2).  I have two that work fine,
but any time I try to write one that uses a text*, postgres crashes.
This is true even for the example functions like "copytext" given in the
documentation here:
http://developer.postgresql.org/pgdocs/postgres/xfunc-c.html

I'm compiling my DLL with MinGW.  I do CREATE FUNCTION as described in
the documentation, and then I do a "SELECT copytext(colname) FROM
tablename" (colname is a text column), at which point Visual Studio's
"Something in postgres.exe crashed.  Do you want to debug?" dialog pops
up.  (Of course, I click no and postgres appears to restart itself.)

Again, I have two other functions (neither of which uses a text*), both
of which I can successfully load into postgres (from the same dll file
as the function that crashes) and use in queries without problems.

Does anyone have any idea why this is happening?

- Dan

Re: custom C function problem

От
Tom Lane
Дата:
"Dan \"Heron\" Myers" <heron@xnapid.com> writes:
> I'm creating some custom C functions to load dynamically from a dll
> (this is Postgres 8.3.1 on Windows XP SP2).  I have two that work fine,
> but any time I try to write one that uses a text*, postgres crashes.

What cases have you gotten to work correctly?

My guess is that you're either messed up about V0 vs V1 calling
convention (ie you forgot PG_FUNCTION_INFO_V1, or added it when you
shouldn't have), or you've got some kind of problem with not detoasting
toasted input values.  There's not enough info here to venture more.

            regards, tom lane

Re: custom C function problem

От
"Dan \"Heron\" Myers"
Дата:
Tom Lane wrote:
> What cases have you gotten to work correctly?
>
> My guess is that you're either messed up about V0 vs V1 calling
> convention (ie you forgot PG_FUNCTION_INFO_V1, or added it when you
> shouldn't have), or you've got some kind of problem with not detoasting
> toasted input values.  There's not enough info here to venture more.
>
>             regards, tom lane

This one works correctly:

PG_FUNCTION_INFO_V1(event_duration);

Datum
event_duration(PG_FUNCTION_ARGS)
{
     int32 state = PG_GETARG_INT32(0);
     int32 target = PG_GETARG_INT32(1);
     int32 event = PG_GETARG_INT32(2);
     Timestamp start = PG_GETARG_TIMESTAMP(3);
     Timestamp end = PG_GETARG_TIMESTAMP(4);

     //If this event is the correct type we need to add the event time
to the total event time (state)
     if(target == event){
         state += (end - start);
     }

     PG_RETURN_INT32(state);
}

I can use event_duration in this query without problems:

SELECT call_id, event_duration(4,event_type,start_time,end_time) AS
talking_duration FROM event GROUP BY call_id;

One case that fails is essentially copied from the V1 section in the
documentation:

PG_FUNCTION_INFO_V1(copytext);

Datum copytext(PG_FUNCTION_ARGS)
{
     text* t = PG_GETARG_TEXT_P(0);
     text* new_t = (text *) palloc(VARSIZE(t));
     SET_VARSIZE(new_t, VARSIZE(t));

     memcpy((void *) VARDATA(new_t), (void *) VARDATA(t),
            VARSIZE(t) - VARHDRSZ);
     PG_RETURN_TEXT_P(new_t);
}

Attempting to use copytext in a query results in Postgres crashing.
For example:

SELECT copytext(calling_party) FROM event;

crashes.

- Dan

Re: custom C function problem

От
Tom Lane
Дата:
"Dan \"Heron\" Myers" <heron@xnapid.com> writes:
> One case that fails is essentially copied from the V1 section in the
> documentation:

Well, there's nothing wrong with that C code, so the problem is
someplace else.

Did you remember to declare the function STRICT?  If not, and if
there are any nulls in your test table, a crash would be expected;
there's nothing in this function that's guarding against a null
pointer dereference.

            regards, tom lane

Re: custom C function problem

От
"Dan \"Heron\" Myers"
Дата:

Tom Lane wrote:
> Well, there's nothing wrong with that C code, so the problem is
> someplace else.
>
> Did you remember to declare the function STRICT?  If not, and if
> there are any nulls in your test table, a crash would be expected;
> there's nothing in this function that's guarding against a null
> pointer dereference.

I did declare the function STRICT, yes.

I'm wondering if maybe there is a dependency somewhere I'm missing.  I
link with postgres.lib to create the dll; I basically made an educated
guess as to what to link with to get rid of linker errors, since the
documentation didn't really say I needed to link with anything, but I
suppose it's possible that there is another .lib somewhere that I should
link with instead.  Is there anyone who has experience writing custom C
functions for Postgres that could weigh in here?

Thanks,
Dan

Re: custom C function problem

От
Tom Lane
Дата:
"Dan \"Heron\" Myers" <heron@xnapid.com> writes:
> I'm wondering if maybe there is a dependency somewhere I'm missing.  I
> link with postgres.lib to create the dll;

Oh, you're using Windows :-(.  I make it my business to not know
anything about that platform, but perhaps you could get a clue by
looking at how the contrib modules are built (using whichever tool
chain you're using).

Or you could put in a few debugging printf's, or poke at it with a
debugger.

            regards, tom lane