From 226e9fffc855da10fcf2a69e49c52f9baf5e6e61 Mon Sep 17 00:00:00 2001 From: Andrew Dunstan Date: Fri, 5 Jan 2007 16:17:55 +0000 Subject: [PATCH] Call setrlimit if possible in pg_regress to allow core file generation, and provide a switch for similar behaviour in pg_ctl. --- doc/src/sgml/ref/pg_ctl-ref.sgml | 17 ++++++++++- src/bin/pg_ctl/pg_ctl.c | 50 ++++++++++++++++++++++++++++++-- src/test/regress/pg_regress.c | 35 +++++++++++++++++++++- 3 files changed, 97 insertions(+), 5 deletions(-) diff --git a/doc/src/sgml/ref/pg_ctl-ref.sgml b/doc/src/sgml/ref/pg_ctl-ref.sgml index df5b3755b5..72fb51b1c7 100644 --- a/doc/src/sgml/ref/pg_ctl-ref.sgml +++ b/doc/src/sgml/ref/pg_ctl-ref.sgml @@ -1,5 +1,5 @@ @@ -29,6 +29,7 @@ PostgreSQL documentation -l filename -o options -p path + -c pg_ctl stop @@ -48,6 +49,7 @@ PostgreSQL documentation -w -s -D datadir + -c -m s[mart] @@ -245,6 +247,19 @@ PostgreSQL documentation + + + + + Attempt to allow server crashes to produce core files, on platforms + where this available, by lifting any soft resource limit placed on + them. + This is useful in debugging or diagnosing problems by allowing a + stack trace to be obtained from a failed server process. + + + + diff --git a/src/bin/pg_ctl/pg_ctl.c b/src/bin/pg_ctl/pg_ctl.c index 57207ebd99..57b3a0db33 100644 --- a/src/bin/pg_ctl/pg_ctl.c +++ b/src/bin/pg_ctl/pg_ctl.c @@ -4,7 +4,7 @@ * * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * - * $PostgreSQL: pgsql/src/bin/pg_ctl/pg_ctl.c,v 1.74 2006/10/12 05:14:49 tgl Exp $ + * $PostgreSQL: pgsql/src/bin/pg_ctl/pg_ctl.c,v 1.75 2007/01/05 16:17:55 adunstan Exp $ * *------------------------------------------------------------------------- */ @@ -26,6 +26,11 @@ #include #include +#ifdef HAVE_SYS_RESOURCE_H +#include +#include +#endif + #include "libpq/pqsignal.h" #include "getopt_long.h" @@ -90,6 +95,7 @@ static char *register_servicename = "PostgreSQL"; /* FIXME: + version ID? */ static char *register_username = NULL; static char *register_password = NULL; static char *argv0 = NULL; +static bool allow_core_files = false; static void write_stderr(const char *fmt,...) @@ -132,6 +138,10 @@ static char postopts_file[MAXPGPATH]; static char pid_file[MAXPGPATH]; static char conf_file[MAXPGPATH]; +#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE) +static void unlimit_core_size(void); +#endif + #if defined(WIN32) || defined(__CYGWIN__) static void @@ -478,6 +488,27 @@ test_postmaster_connection(void) } +#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE) +static void +unlimit_core_size(void) +{ + struct rlimit lim; + getrlimit(RLIMIT_CORE,&lim); + if (lim.rlim_max == 0) + { + write_stderr(_("%s: cannot set core size, disallowed by hard limit.\n"), + progname); + return; + } + else if (lim.rlim_max == RLIM_INFINITY || lim.rlim_cur < lim.rlim_max) + { + lim.rlim_cur = lim.rlim_max; + setrlimit(RLIMIT_CORE,&lim); + } +} +#endif + + static void do_start(void) @@ -581,6 +612,11 @@ do_start(void) postgres_path = postmaster_path; } +#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE) + if (allow_core_files) + unlimit_core_size(); +#endif + exitcode = start_postmaster(); if (exitcode != 0) { @@ -1401,7 +1437,11 @@ do_help(void) printf(_(" -o OPTIONS command line options to pass to postgres\n" " (PostgreSQL server executable)\n")); printf(_(" -p PATH-TO-POSTGRES normally not necessary\n")); - +#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE) + printf(_(" -c, --core-files allow postgres to produce core files\n")); +#else + printf(_(" -c, --core-files not applicable on this platform\n")); +#endif printf(_("\nOptions for stop or restart:\n")); printf(_(" -m SHUTDOWN-MODE may be \"smart\", \"fast\", or \"immediate\"\n")); @@ -1497,6 +1537,7 @@ main(int argc, char **argv) {"mode", required_argument, NULL, 'm'}, {"pgdata", required_argument, NULL, 'D'}, {"silent", no_argument, NULL, 's'}, + {"core-files", no_argument, NULL, 'c'}, {NULL, 0, NULL, 0} }; @@ -1561,7 +1602,7 @@ main(int argc, char **argv) /* process command-line options */ while (optind < argc) { - while ((c = getopt_long(argc, argv, "D:l:m:N:o:p:P:sU:wW", long_options, &option_index)) != -1) + while ((c = getopt_long(argc, argv, "cD:l:m:N:o:p:P:sU:wW", long_options, &option_index)) != -1) { switch (c) { @@ -1632,6 +1673,9 @@ main(int argc, char **argv) do_wait = false; wait_set = true; break; + case 'c': + allow_core_files = true; + break; default: /* getopt_long already issued a suitable error message */ do_advice(); diff --git a/src/test/regress/pg_regress.c b/src/test/regress/pg_regress.c index 5daf28a666..236be9456d 100644 --- a/src/test/regress/pg_regress.c +++ b/src/test/regress/pg_regress.c @@ -11,7 +11,7 @@ * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/test/regress/pg_regress.c,v 1.23 2006/10/04 00:30:14 momjian Exp $ + * $PostgreSQL: pgsql/src/test/regress/pg_regress.c,v 1.24 2007/01/05 16:17:55 adunstan Exp $ * *------------------------------------------------------------------------- */ @@ -24,6 +24,11 @@ #include #include +#ifdef HAVE_SYS_RESOURCE_H +#include +#include +#endif + #include "getopt_long.h" #include "pg_config_paths.h" @@ -122,6 +127,30 @@ psql_command(const char *database, const char *query,...) the supplied arguments. */ __attribute__((format(printf, 2, 3))); +/* + * allow core files if possible. + */ +#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE) +static void +unlimit_core_size(void) +{ + struct rlimit lim; + getrlimit(RLIMIT_CORE,&lim); + if (lim.rlim_max == 0) + { + fprintf(stderr, + _("%s: cannot set core size,: disallowed by hard limit.\n"), + progname); + return; + } + else if (lim.rlim_max == RLIM_INFINITY || lim.rlim_cur < lim.rlim_max) + { + lim.rlim_cur = lim.rlim_max; + setrlimit(RLIMIT_CORE,&lim); + } +} +#endif + /* * Add an item at the end of a stringlist. @@ -1459,6 +1488,10 @@ main(int argc, char *argv[]) initialize_environment(); +#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE) + unlimit_core_size(); +#endif + if (temp_install) { /* -- 2.40.0