Обсуждение: custom C function problem
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
"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
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
"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
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
"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