Hi All,
While running test with bind varible getting segmentation fault. ( CVS Head
8.4)
For testcase, please find the crash.c (C test) and test.java ( JDBC test)
attached with the mail.
Had a quick look at the core dump and found the call stack for the
segmentation fault.
(gdb) bt
#0 0x0813768d in analyze_requires_snapshot (parseTree=0x0) at analyze.c:270
#1 0x082e77a8 in exec_bind_message (input_message=0xbfd7d73c) at
postgres.c:1698
#2 0x082ec524 in PostgresMain (argc=4, argv=0x916fc70, username=0x916fb7c
"rushabh") at postgres.c:4882
#3 0x082ac10a in BackendRun (port=0x9191b18) at postmaster.c:3309
#4 0x082ab4d4 in BackendStartup (port=0x9191b18) at postmaster.c:2881
#5 0x082a8ae1 in ServerLoop () at postmaster.c:1291
Had a look at the previous version and found that because of following
condition added with the new PG merge into exec_bind_message(); we end up
with the segmentation fault.
exec_bind_message{
...
/*
* Set a snapshot if we have parameters to fetch (since the input
* functions might need it) or the query isn't a utility command (and
* hence could require redoing parse analysis and planning).
*/
if (numParams > 0 || analyze_requires_snapshot(psrc->raw_parse_tree))
{
PushActiveSnapshot(GetTransactionSnapshot());
snapshot_set = true;
}
...
}
Condition added with "Fix failure to ensure that a snapshot is available to
datatype input functions" commit. (
http://git.postgresql.org/?p=postgresql.git;a=commitdiff;h=d5e7e5dd7c81440bb46f52872906633ee2b388c1
)
Not very much sure but for the quick check I just modifiled condition by
added check for raw_parse_tree and test worked file.
Modified condition:
/*
* Set a snapshot if we have parameters to fetch (since the input
* functions might need it) or the query isn't a utility command (and
* hence could require redoing parse analysis and planning).
*/
if (numParams > 0 ||
(psrc->raw_parse_tree &&
analyze_requires_snapshot(psrc->raw_parse_tree)))
{
PushActiveSnapshot(GetTransactionSnapshot());
snapshot_set = true;
}
Another fix would be to add check for parseTree into
analyze_requires_snapshot().
Thanks ,
Rushabh Lathia
www.EnterpriseDB.com
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.*;
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
try {
Class.forName("org.postgresql.Driver");
Connection con = DriverManager.getConnection("jdbc:postgresql://localhost:5432/postgres?loglevel=2","rushabh","edb");
PreparedStatement st;
ResultSet rs;
st = con.prepareStatement("SELECT ?;--SELECT ?");
st.setString(1, "a");
st.execute(); st.getMoreResults();
st.getMoreResults();
st.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include "libpq-fe.h"
int
main(int argc, char **argv)
{
const char *conninfo;
PGconn *conn;
PGresult *res;
/*
* If the user supplies a parameter on the command line, use it as the
* conninfo string; otherwise default to setting dbname=postgres and using
* environment variables or defaults for all other connection parameters.
*/
if (argc > 1)
conninfo = argv[1];
else
conninfo = "dbname = postgres";
/* Make a connection to the database */
conn = PQconnectdb(conninfo);
/* Check to see that the backend connection was successfully made */
if (PQstatus(conn) != CONNECTION_OK)
{
fprintf(stderr, "Connection to database failed: %s",
PQerrorMessage(conn));
return 1;
}
res = PQexecParams(conn,
"/* nothing */",
0, /* no params */
NULL, /* let the backend deduce param type */
NULL,
NULL, /* don't need param lengths since text */
NULL, /* default to all text params */
0);
if (PQresultStatus(res) != PGRES_TUPLES_OK)
{
fprintf(stderr, "query failed: %s", PQerrorMessage(conn));
}
PQclear(res);
/* close the connection to the database and cleanup */
PQfinish(conn);
return 0;
}
--
Sent via pgsql-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers