public inbox for [email protected]  
help / color / mirror / Atom feed
From: Andrey Lepikhov <[email protected]>
To: Craig Ringer <[email protected]>
To: pgsql-hackers <[email protected]>
Subject: Re: POC: GUC option for skipping shared buffers in core dumps
Date: Mon, 25 Sep 2023 16:42:35 +0700
Message-ID: <[email protected]> (raw)
In-Reply-To: <CAMsr+YGPUpxOZ5u2Zk+qGorz-ZyES96u0KMVKy4mYvR2w7bpJg@mail.gmail.com>
References: <CAPpHfdscDF3MofD6MgnnhZoJ-Jek+awxzKie4cS9LJftup746A@mail.gmail.com>
	<CAMsr+YGPUpxOZ5u2Zk+qGorz-ZyES96u0KMVKy4mYvR2w7bpJg@mail.gmail.com>

Hi,

The current approach could be better because we want to use it on 
Windows/MacOS and other systems. So, I've tried to develop another 
strategy - detaching shmem and DSM blocks before executing the abort() 
routine.
As I can see, it helps and reduces the size of the core file.

-- 
regards,
Andrey Lepikhov
Postgres Professional

diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c
index 5810f8825e..4d7bf2c0e4 100644
--- a/src/backend/bootstrap/bootstrap.c
+++ b/src/backend/bootstrap/bootstrap.c
@@ -325,7 +325,7 @@ BootstrapModeMain(int argc, char *argv[], bool check_only)
 	{
 		SetProcessingMode(NormalProcessing);
 		CheckerModeMain();
-		abort();
+		pg_abort();
 	}
 
 	/*
diff --git a/src/backend/main/main.c b/src/backend/main/main.c
index ed11e8be7f..34ac874ad0 100644
--- a/src/backend/main/main.c
+++ b/src/backend/main/main.c
@@ -197,7 +197,7 @@ main(int argc, char *argv[])
 	else
 		PostmasterMain(argc, argv);
 	/* the functions above should not return */
-	abort();
+	pg_abort();
 }
 
 
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index 54e9bfb8c4..fc32a6bb1b 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -1469,7 +1469,7 @@ PostmasterMain(int argc, char *argv[])
 	 */
 	ExitPostmaster(status != STATUS_OK);
 
-	abort();					/* not reached */
+	pg_abort();					/* not reached */
 }
 
 
diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c
index e250b0567e..3123b388ab 100644
--- a/src/backend/replication/walsender.c
+++ b/src/backend/replication/walsender.c
@@ -385,7 +385,7 @@ WalSndShutdown(void)
 		whereToSendOutput = DestNone;
 
 	proc_exit(0);
-	abort();					/* keep the compiler quiet */
+	pg_abort();					/* keep the compiler quiet */
 }
 
 /*
diff --git a/src/backend/utils/error/assert.c b/src/backend/utils/error/assert.c
index 719dd7b309..f422d42440 100644
--- a/src/backend/utils/error/assert.c
+++ b/src/backend/utils/error/assert.c
@@ -19,6 +19,32 @@
 #include <execinfo.h>
 #endif
 
+#include <storage/dsm.h>
+#include <storage/pg_shmem.h>
+
+int core_dump_no_shared_buffers = COREDUMP_INCLUDE_ALL;
+
+/*
+ * Remember, at the same time someone can work with shared memory, write them to
+ * disk and so on.
+ */
+void
+pg_abort(void)
+{
+	if (core_dump_no_shared_buffers != COREDUMP_INCLUDE_ALL)
+	{
+		if (core_dump_no_shared_buffers == COREDUMP_EXCLUDE_ALL ||
+			core_dump_no_shared_buffers == COREDUMP_EXCLUDE_DSM)
+			dsm_detach_all();
+
+		if (core_dump_no_shared_buffers == COREDUMP_EXCLUDE_ALL ||
+			core_dump_no_shared_buffers == COREDUMP_EXCLUDE_SHMEM)
+			PGSharedMemoryDetach();
+	}
+
+	abort();
+}
+
 /*
  * ExceptionalCondition - Handles the failure of an Assert()
  *
@@ -63,5 +89,5 @@ ExceptionalCondition(const char *conditionName,
 	sleep(1000000);
 #endif
 
-	abort();
+	pg_abort();
 }
diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c
index 8e1f3e8521..f6c863ca68 100644
--- a/src/backend/utils/error/elog.c
+++ b/src/backend/utils/error/elog.c
@@ -601,7 +601,7 @@ errfinish(const char *filename, int lineno, const char *funcname)
 		 * children...
 		 */
 		fflush(NULL);
-		abort();
+		pg_abort();
 	}
 
 	/*
diff --git a/src/backend/utils/misc/guc_tables.c b/src/backend/utils/misc/guc_tables.c
index bdb26e2b77..95e205e8d1 100644
--- a/src/backend/utils/misc/guc_tables.c
+++ b/src/backend/utils/misc/guc_tables.c
@@ -427,6 +427,14 @@ static const struct config_enum_entry debug_logical_replication_streaming_option
 	{NULL, 0, false}
 };
 
+static const struct config_enum_entry core_dump_no_shared_buffers_options[] = {
+	{"none", COREDUMP_INCLUDE_ALL, false},
+	{"shmem", COREDUMP_EXCLUDE_SHMEM, false},
+	{"dsm", COREDUMP_EXCLUDE_DSM, false},
+	{"all", COREDUMP_EXCLUDE_ALL, false},
+	{NULL, 0, false}
+};
+
 StaticAssertDecl(lengthof(ssl_protocol_versions_info) == (PG_TLS1_3_VERSION + 2),
 				 "array length mismatch");
 
@@ -4971,6 +4979,17 @@ struct config_enum ConfigureNamesEnum[] =
 		NULL, NULL, NULL
 	},
 
+	{
+		{"core_dump_no_shared_buffers", PGC_POSTMASTER, DEVELOPER_OPTIONS,
+			NULL,
+			NULL,
+			GUC_NOT_IN_SAMPLE
+		},
+		&core_dump_no_shared_buffers,
+		COREDUMP_INCLUDE_ALL, core_dump_no_shared_buffers_options,
+		NULL, NULL, NULL
+	},
+
 	/* End-of-list marker */
 	{
 		{NULL, 0, 0, NULL, NULL}, NULL, 0, NULL, NULL, NULL, NULL
diff --git a/src/include/c.h b/src/include/c.h
index 82f8e9d4c7..2c9cfedc60 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -892,6 +892,18 @@ typedef NameData *Name;
 #ifndef FRONTEND
 extern void ExceptionalCondition(const char *conditionName,
 								 const char *fileName, int lineNumber) pg_attribute_noreturn();
+
+/* possible values for core_dump_no_shared_buffers */
+typedef enum
+{
+	COREDUMP_INCLUDE_ALL,
+	COREDUMP_EXCLUDE_SHMEM,
+	COREDUMP_EXCLUDE_DSM,
+	COREDUMP_EXCLUDE_ALL
+}			CoreDumpGenerationMode;
+
+extern int core_dump_no_shared_buffers;
+void pg_abort(void);
 #endif
 
 /*


Attachments:

  [text/plain] detach_on_abort.diff (4.6K, ../[email protected]/2-detach_on_abort.diff)
  download | inline diff:
diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c
index 5810f8825e..4d7bf2c0e4 100644
--- a/src/backend/bootstrap/bootstrap.c
+++ b/src/backend/bootstrap/bootstrap.c
@@ -325,7 +325,7 @@ BootstrapModeMain(int argc, char *argv[], bool check_only)
 	{
 		SetProcessingMode(NormalProcessing);
 		CheckerModeMain();
-		abort();
+		pg_abort();
 	}
 
 	/*
diff --git a/src/backend/main/main.c b/src/backend/main/main.c
index ed11e8be7f..34ac874ad0 100644
--- a/src/backend/main/main.c
+++ b/src/backend/main/main.c
@@ -197,7 +197,7 @@ main(int argc, char *argv[])
 	else
 		PostmasterMain(argc, argv);
 	/* the functions above should not return */
-	abort();
+	pg_abort();
 }
 
 
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index 54e9bfb8c4..fc32a6bb1b 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -1469,7 +1469,7 @@ PostmasterMain(int argc, char *argv[])
 	 */
 	ExitPostmaster(status != STATUS_OK);
 
-	abort();					/* not reached */
+	pg_abort();					/* not reached */
 }
 
 
diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c
index e250b0567e..3123b388ab 100644
--- a/src/backend/replication/walsender.c
+++ b/src/backend/replication/walsender.c
@@ -385,7 +385,7 @@ WalSndShutdown(void)
 		whereToSendOutput = DestNone;
 
 	proc_exit(0);
-	abort();					/* keep the compiler quiet */
+	pg_abort();					/* keep the compiler quiet */
 }
 
 /*
diff --git a/src/backend/utils/error/assert.c b/src/backend/utils/error/assert.c
index 719dd7b309..f422d42440 100644
--- a/src/backend/utils/error/assert.c
+++ b/src/backend/utils/error/assert.c
@@ -19,6 +19,32 @@
 #include <execinfo.h>
 #endif
 
+#include <storage/dsm.h>
+#include <storage/pg_shmem.h>
+
+int core_dump_no_shared_buffers = COREDUMP_INCLUDE_ALL;
+
+/*
+ * Remember, at the same time someone can work with shared memory, write them to
+ * disk and so on.
+ */
+void
+pg_abort(void)
+{
+	if (core_dump_no_shared_buffers != COREDUMP_INCLUDE_ALL)
+	{
+		if (core_dump_no_shared_buffers == COREDUMP_EXCLUDE_ALL ||
+			core_dump_no_shared_buffers == COREDUMP_EXCLUDE_DSM)
+			dsm_detach_all();
+
+		if (core_dump_no_shared_buffers == COREDUMP_EXCLUDE_ALL ||
+			core_dump_no_shared_buffers == COREDUMP_EXCLUDE_SHMEM)
+			PGSharedMemoryDetach();
+	}
+
+	abort();
+}
+
 /*
  * ExceptionalCondition - Handles the failure of an Assert()
  *
@@ -63,5 +89,5 @@ ExceptionalCondition(const char *conditionName,
 	sleep(1000000);
 #endif
 
-	abort();
+	pg_abort();
 }
diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c
index 8e1f3e8521..f6c863ca68 100644
--- a/src/backend/utils/error/elog.c
+++ b/src/backend/utils/error/elog.c
@@ -601,7 +601,7 @@ errfinish(const char *filename, int lineno, const char *funcname)
 		 * children...
 		 */
 		fflush(NULL);
-		abort();
+		pg_abort();
 	}
 
 	/*
diff --git a/src/backend/utils/misc/guc_tables.c b/src/backend/utils/misc/guc_tables.c
index bdb26e2b77..95e205e8d1 100644
--- a/src/backend/utils/misc/guc_tables.c
+++ b/src/backend/utils/misc/guc_tables.c
@@ -427,6 +427,14 @@ static const struct config_enum_entry debug_logical_replication_streaming_option
 	{NULL, 0, false}
 };
 
+static const struct config_enum_entry core_dump_no_shared_buffers_options[] = {
+	{"none", COREDUMP_INCLUDE_ALL, false},
+	{"shmem", COREDUMP_EXCLUDE_SHMEM, false},
+	{"dsm", COREDUMP_EXCLUDE_DSM, false},
+	{"all", COREDUMP_EXCLUDE_ALL, false},
+	{NULL, 0, false}
+};
+
 StaticAssertDecl(lengthof(ssl_protocol_versions_info) == (PG_TLS1_3_VERSION + 2),
 				 "array length mismatch");
 
@@ -4971,6 +4979,17 @@ struct config_enum ConfigureNamesEnum[] =
 		NULL, NULL, NULL
 	},
 
+	{
+		{"core_dump_no_shared_buffers", PGC_POSTMASTER, DEVELOPER_OPTIONS,
+			NULL,
+			NULL,
+			GUC_NOT_IN_SAMPLE
+		},
+		&core_dump_no_shared_buffers,
+		COREDUMP_INCLUDE_ALL, core_dump_no_shared_buffers_options,
+		NULL, NULL, NULL
+	},
+
 	/* End-of-list marker */
 	{
 		{NULL, 0, 0, NULL, NULL}, NULL, 0, NULL, NULL, NULL, NULL
diff --git a/src/include/c.h b/src/include/c.h
index 82f8e9d4c7..2c9cfedc60 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -892,6 +892,18 @@ typedef NameData *Name;
 #ifndef FRONTEND
 extern void ExceptionalCondition(const char *conditionName,
 								 const char *fileName, int lineNumber) pg_attribute_noreturn();
+
+/* possible values for core_dump_no_shared_buffers */
+typedef enum
+{
+	COREDUMP_INCLUDE_ALL,
+	COREDUMP_EXCLUDE_SHMEM,
+	COREDUMP_EXCLUDE_DSM,
+	COREDUMP_EXCLUDE_ALL
+}			CoreDumpGenerationMode;
+
+extern int core_dump_no_shared_buffers;
+void pg_abort(void);
 #endif
 
 /*


view thread (2+ messages)

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: [email protected]
  Cc: [email protected], [email protected]
  Subject: Re: POC: GUC option for skipping shared buffers in core dumps
  In-Reply-To: <[email protected]>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox