Segmentation fault in volatile c function

From: Louise Grandjonc <louve(dot)grandjonc(at)gmail(dot)com>
To: pgsql-general(at)lists(dot)postgresql(dot)org
Subject: Segmentation fault in volatile c function
Date: 2021-10-27 19:39:41
Message-ID: 5FEFE970-6A6B-454E-A3C7-FFD0FAAFDABD@gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-general

Hi,

I'm creating my first ever extension. The function that I'm trying to write takes the schema and name of a table, and adds it in a table with all the tables the extension follows.
In that table I want the schema, name and oid of the table.

I created a C function for that. Here is the code

```
Datum add_mygreat_table(PG_FUNCTION_ARGS);

PG_FUNCTION_INFO_V1(add_mygreat_table);

Datum add_mygreat_table(PG_FUNCTION_ARGS) {
char *tableSchema,
*tableName;

Oid tableNamespace,
relationId;

tableSchema = PG_GETARG_CSTRING(0);
tableName = PG_GETARG_CSTRING(1);

tableNamespace = get_namespace_oid(tableSchema, false);
relationId = get_relname_relid(tableName, tableNamespace);

if (relationId == NULL)
{
ereport(ERROR, (errmsg("could not create remote table: "
"relation does not exist")));
}

Datum values[3];
bool isNulls[3];
memset(isNulls, false, sizeof(isNulls));

values[0] = CStringGetTextDatum(tableSchema);
values[1] = CStringGetTextDatum(tableName);
values[2] = ObjectIdGetDatum(relationId);

Relation greatTable = table_open(MyGreatTablesRelationId(), RowExclusiveLock);

HeapTuple tuple = heap_form_tuple(RelationGetDescr(greatTable), values, isNulls);

/*
* CatalogTupleInsert() is originally for PostgreSQL's catalog. However,
* it is used at here for convenience.
*/
CatalogTupleInsert(greatTable, tuple);

table_close(greatTable, RowExclusiveLock);
heap_freetuple(tuple);

CommandCounterIncrement();

ereport(NOTICE,
(errmsg("Table %s is now a great table", tableName)));

PG_RETURN_BOOL(true);
}
```

And in the sql I have

```
CREATE OR REPLACE FUNCTION mygreat.add_mygreat_table(cstring, cstring)
RETURNS bool
LANGUAGE C STRICT IMMUTABLE
AS '$libdir/mygreat',
$$add_mygreat_table$$;
```

Here is my problem, it works as expected when the table doesn't exist.

```
mygreat_test=# create extension hydra;

CREATE EXTENSION
mygreat_test=# select mygreat.add_mygreat_table('public', 'sampledata3');
ERROR: could not create remote table: relation does not exist
```

However if the table exists it just completely crashes

```
hydra_test=# select hydra.add_remote_table('snowflake', 'public', 'sampledata2');
NOTICE: Table sampledata2 is now a mygreat table
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 figured that it was because of the `IMMUTABLE` as the function does modify the database. And according to documentation

```
IMMUTABLE indicates that the function cannot modify the database and always returns the same result when given the same argument values; t
```

So I tried creating it as a `VOLATILE` function.

```
CREATE OR REPLACE FUNCTION hydra.add_remote_table(cstring, cstring)
RETURNS bool
LANGUAGE C STRICT VOLATILE
AS '$libdir/mygreat',
$$add_mygreat_table$$;
CREATE FUNCTION
```

But now it just always crashes, and what used to return the proper error message when ran against a table that doesn't exist now returns

```
mygreat_test=# select mygreat.add_mygreat_table('public', 'sampledata3');
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.
```

In the logs, for the latest, I get

```
2021-10-27 12:28:02.712 PDT [44115] LOG: statement: select mygreat.add_mygreat_table('public', 'sampledata3');
2021-10-27 12:28:02.718 PDT [43936] LOG: server process (PID 44115) was terminated by signal 11: Segmentation fault: 11
2021-10-27 12:28:02.718 PDT [43936] DETAIL: Failed process was running: select mygreat.add_mygreat_table('public', 'sampledata3');
2021-10-27 12:28:02.719 PDT [43936] LOG: terminating any other active server processes
```

What am I doing wrong? Can anyone help me with this?

Thank you!

Responses

Browse pgsql-general by date

  From Date Subject
Next Message Peter Geoghegan 2021-10-27 19:47:48 Re: Segmentation fault in volatile c function
Previous Message tomas 2021-10-27 18:58:07 jsonb: unwrapping text