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)
{
/*