Change ps_status.c to explicitly track the current logical length of ps_buffer.

This saves cycles in get_ps_display() on many popular platforms, and more
importantly ensures that get_ps_display() will correctly return an empty
string if init_ps_display() hasn't been called yet.  Per trouble report
from Ray Stell, in which log_line_prefix %i produced junk early in backend
startup.

Back-patch to 8.0.  7.4 doesn't have %i and its version of get_ps_display()
makes no pretense of avoiding pad junk anyhow.
This commit is contained in:
Tom Lane 2010-05-27 19:19:38 +00:00
parent 2175d4fa59
commit ede5072676
1 changed files with 18 additions and 28 deletions

View File

@ -5,7 +5,7 @@
* to contain some useful information. Mechanism differs wildly across * to contain some useful information. Mechanism differs wildly across
* platforms. * platforms.
* *
* $PostgreSQL: pgsql/src/backend/utils/misc/ps_status.c,v 1.40 2010/01/02 16:57:58 momjian Exp $ * $PostgreSQL: pgsql/src/backend/utils/misc/ps_status.c,v 1.41 2010/05/27 19:19:38 tgl Exp $
* *
* Copyright (c) 2000-2010, PostgreSQL Global Development Group * Copyright (c) 2000-2010, PostgreSQL Global Development Group
* various details abducted from various places * various details abducted from various places
@ -51,7 +51,7 @@ bool update_process_title = true;
* (some other BSD systems) * (some other BSD systems)
* PS_USE_CLOBBER_ARGV * PS_USE_CLOBBER_ARGV
* write over the argv and environment area * write over the argv and environment area
* (most SysV-like systems) * (Linux and most SysV-like systems)
* PS_USE_WIN32 * PS_USE_WIN32
* push the string out as the name of a Windows event * push the string out as the name of a Windows event
* PS_USE_NONE * PS_USE_NONE
@ -84,7 +84,7 @@ bool update_process_title = true;
#ifndef PS_USE_CLOBBER_ARGV #ifndef PS_USE_CLOBBER_ARGV
/* all but one options need a buffer to write their ps line in */ /* all but one option need a buffer to write their ps line in */
#define PS_BUFFER_SIZE 256 #define PS_BUFFER_SIZE 256
static char ps_buffer[PS_BUFFER_SIZE]; static char ps_buffer[PS_BUFFER_SIZE];
static const size_t ps_buffer_size = PS_BUFFER_SIZE; static const size_t ps_buffer_size = PS_BUFFER_SIZE;
@ -94,6 +94,8 @@ static size_t ps_buffer_size; /* space determined at run time */
static size_t last_status_len; /* use to minimize length of clobber */ static size_t last_status_len; /* use to minimize length of clobber */
#endif /* PS_USE_CLOBBER_ARGV */ #endif /* PS_USE_CLOBBER_ARGV */
static size_t ps_buffer_cur_len; /* nominal strlen(ps_buffer) */
static size_t ps_buffer_fixed_size; /* size of the constant prefix */ static size_t ps_buffer_fixed_size; /* size of the constant prefix */
/* save the original argv[] location here */ /* save the original argv[] location here */
@ -226,6 +228,7 @@ init_ps_display(const char *username, const char *dbname,
/* no ps display if you didn't call save_ps_display_args() */ /* no ps display if you didn't call save_ps_display_args() */
if (!save_argv) if (!save_argv)
return; return;
#ifdef PS_USE_CLOBBER_ARGV #ifdef PS_USE_CLOBBER_ARGV
/* If ps_buffer is a pointer, it might still be null */ /* If ps_buffer is a pointer, it might still be null */
if (!ps_buffer) if (!ps_buffer)
@ -270,7 +273,7 @@ init_ps_display(const char *username, const char *dbname,
username, dbname, host_info); username, dbname, host_info);
#endif #endif
ps_buffer_fixed_size = strlen(ps_buffer); ps_buffer_cur_len = ps_buffer_fixed_size = strlen(ps_buffer);
set_ps_display(initial_str, true); set_ps_display(initial_str, true);
#endif /* not PS_USE_NONE */ #endif /* not PS_USE_NONE */
@ -285,11 +288,11 @@ init_ps_display(const char *username, const char *dbname,
void void
set_ps_display(const char *activity, bool force) set_ps_display(const char *activity, bool force)
{ {
#ifndef PS_USE_NONE
/* update_process_title=off disables updates, unless force = true */
if (!force && !update_process_title) if (!force && !update_process_title)
return; return;
#ifndef PS_USE_NONE
/* no ps display for stand-alone backend */ /* no ps display for stand-alone backend */
if (!IsUnderPostmaster) if (!IsUnderPostmaster)
return; return;
@ -303,6 +306,7 @@ set_ps_display(const char *activity, bool force)
/* Update ps_buffer to contain both fixed part and activity */ /* Update ps_buffer to contain both fixed part and activity */
strlcpy(ps_buffer + ps_buffer_fixed_size, activity, strlcpy(ps_buffer + ps_buffer_fixed_size, activity,
ps_buffer_size - ps_buffer_fixed_size); ps_buffer_size - ps_buffer_fixed_size);
ps_buffer_cur_len = strlen(ps_buffer);
/* Transmit new setting to kernel, if necessary */ /* Transmit new setting to kernel, if necessary */
@ -315,7 +319,7 @@ set_ps_display(const char *activity, bool force)
union pstun pst; union pstun pst;
pst.pst_command = ps_buffer; pst.pst_command = ps_buffer;
pstat(PSTAT_SETCMD, pst, strlen(ps_buffer), 0, 0); pstat(PSTAT_SETCMD, pst, ps_buffer_cur_len, 0, 0);
} }
#endif /* PS_USE_PSTAT */ #endif /* PS_USE_PSTAT */
@ -325,16 +329,11 @@ set_ps_display(const char *activity, bool force)
#endif /* PS_USE_PS_STRINGS */ #endif /* PS_USE_PS_STRINGS */
#ifdef PS_USE_CLOBBER_ARGV #ifdef PS_USE_CLOBBER_ARGV
{ /* pad unused memory; need only clobber remainder of old status string */
int buflen; if (last_status_len > ps_buffer_cur_len)
MemSet(ps_buffer + ps_buffer_cur_len, PS_PADDING,
/* pad unused memory */ last_status_len - ps_buffer_cur_len);
buflen = strlen(ps_buffer); last_status_len = ps_buffer_cur_len;
/* clobber remainder of old status string */
if (last_status_len > buflen)
MemSet(ps_buffer + buflen, PS_PADDING, last_status_len - buflen);
last_status_len = buflen;
}
#endif /* PS_USE_CLOBBER_ARGV */ #endif /* PS_USE_CLOBBER_ARGV */
#ifdef PS_USE_WIN32 #ifdef PS_USE_WIN32
@ -369,24 +368,15 @@ const char *
get_ps_display(int *displen) get_ps_display(int *displen)
{ {
#ifdef PS_USE_CLOBBER_ARGV #ifdef PS_USE_CLOBBER_ARGV
size_t offset;
/* If ps_buffer is a pointer, it might still be null */ /* If ps_buffer is a pointer, it might still be null */
if (!ps_buffer) if (!ps_buffer)
{ {
*displen = 0; *displen = 0;
return ""; return "";
} }
/* Remove any trailing spaces to offset the effect of PS_PADDING */
offset = ps_buffer_size;
while (offset > ps_buffer_fixed_size && ps_buffer[offset - 1] == PS_PADDING)
offset--;
*displen = offset - ps_buffer_fixed_size;
#else
*displen = strlen(ps_buffer + ps_buffer_fixed_size);
#endif #endif
*displen = (int) (ps_buffer_cur_len - ps_buffer_fixed_size);
return ps_buffer + ps_buffer_fixed_size; return ps_buffer + ps_buffer_fixed_size;
} }