diff --git a/src/backend/utils/misc/ps_status.c b/src/backend/utils/misc/ps_status.c
index 5d829e6e483..f8035c15df8 100644
--- a/src/backend/utils/misc/ps_status.c
+++ b/src/backend/utils/misc/ps_status.c
@@ -23,8 +23,6 @@
 #include "utils/guc.h"
 #include "utils/ps_status.h"
 
-extern char **environ;
-
 /* GUC variable */
 bool		update_process_title = DEFAULT_UPDATE_PROCESS_TITLE;
 
@@ -38,7 +36,7 @@ bool		update_process_title = DEFAULT_UPDATE_PROCESS_TITLE;
  *	   use the function setproctitle(const char *, ...)
  *	   (other BSDs)
  * PS_USE_CLOBBER_ARGV
- *	   write over the argv and environment area
+ *	   write over the argv area
  *	   (Linux and most SysV-like systems)
  * PS_USE_WIN32
  *	   push the string out as the name of a Windows event
@@ -69,9 +67,9 @@ bool		update_process_title = DEFAULT_UPDATE_PROCESS_TITLE;
 
 #ifndef PS_USE_NONE
 
-#ifndef PS_USE_CLOBBER_ARGV
 /* all but one option need a buffer to write their ps line in */
 #define PS_BUFFER_SIZE 256
+#ifndef PS_USE_CLOBBER_ARGV
 static char ps_buffer[PS_BUFFER_SIZE];
 static const size_t ps_buffer_size = PS_BUFFER_SIZE;
 #else							/* PS_USE_CLOBBER_ARGV */
@@ -105,9 +103,7 @@ static char **save_argv;
  * from being clobbered by subsequent ps_display actions.
  *
  * (The original argv[] will not be overwritten by this routine, but may be
- * overwritten during init_ps_display.  Also, the physical location of the
- * environment strings may be moved, so this should be called before any code
- * that might try to hang onto a getenv() result.)
+ * overwritten during init_ps_display.)
  *
  * Note that in case of failure this cannot call elog() as that is not
  * initialized yet.  We rely on write_stderr() instead.
@@ -126,7 +122,6 @@ save_ps_display_args(int argc, char **argv)
 	 */
 	{
 		char	   *end_of_area = NULL;
-		char	  **new_environ;
 		int			i;
 
 		/*
@@ -145,38 +140,32 @@ save_ps_display_args(int argc, char **argv)
 			return argv;
 		}
 
-		/*
-		 * check for contiguous environ strings following argv
-		 */
-		for (i = 0; environ[i] != NULL; i++)
-		{
-			if (end_of_area + 1 == environ[i])
-				end_of_area = environ[i] + strlen(environ[i]);
-		}
-
 		ps_buffer = argv[0];
 		last_status_len = ps_buffer_size = end_of_area - argv[0];
 
-		/*
-		 * move the environment out of the way
-		 */
-		new_environ = (char **) malloc((i + 1) * sizeof(char *));
-		if (!new_environ)
+		if (ps_buffer_size < PS_BUFFER_SIZE)
 		{
-			write_stderr("out of memory\n");
+			char    *argv0_padded;
+			int		 len = strlen(argv[0]);
+			char	*self = argv[0];
+
+			/* right pad argv[0] with slashes up to PS_BUFFER_SIZE */
+			argv0_padded = (char *) malloc(len + PS_BUFFER_SIZE - ps_buffer_size);
+			memcpy(argv0_padded, argv[0], len);
+			MemSet(argv0_padded + len, '/', PS_BUFFER_SIZE - len - 1);
+			argv[0] = argv0_padded;
+
+			execvp(self, argv);
+			write_stderr("exec failed: %s\n%s", strerror(errno), self);
 			exit(1);
 		}
-		for (i = 0; environ[i] != NULL; i++)
+		else
 		{
-			new_environ[i] = strdup(environ[i]);
-			if (!new_environ[i])
-			{
-				write_stderr("out of memory\n");
-				exit(1);
-			}
+			/* We might have already padded argv[0], so we must strip
+		 	 * it again to make get_program_name work. */
+			int		len = strlen(argv[0]);
+			while (len > 0 && argv[0][len - 1] == '/') argv[0][--len] = '\0';
 		}
-		new_environ[i] = NULL;
-		environ = new_environ;
 	}
 
 	/*
-- 
2.44.0

