gdb: split array and string limiting options

Message ID 20211007131451.849029-1-andrew.burgess@embecosm.com
State New
Headers show
Series
  • gdb: split array and string limiting options
Related show

Commit Message

Andrew Burgess Oct. 7, 2021, 1:14 p.m.
This commit splits the set/show print elements options into two.  We
retain set/show print elements for controlling how many elements of an
array we print, but a new set/show print characters is added which is
used for controlling how many characters of a string are printed.

The motivation behind this change is to allow users a finer level of
control over how data is printed, reflecting that, although strings
can be thought of as arrays of characters, users often want to treat
these two things differently.

The GDB changes are all pretty straight forward, just changing
references to the old 'print_max' to reference the new 'print_smax'
setting.

Likewise, the documentation is just updated to reference the new
setting where appropriate.

In the testsuite, most of the changes are places where I've either
changed to using 'set print characters' instead of 'set print
elements', or I set both together as the subsequent tests were a mix
of arrays and strings.

There's new tests for Ada and Pascal, as the string printing code for
these languages is different than the generic string printing code
used by other languages.  Modula2 also has different string printing
code, but (a) this is similar to Pascal, and (b) there are no existing
modula2 tests written in Modula2, so I'm not sure how I'd even test
the Modula2 string printing.

There's also a few places where GDB used 'show print elements', the
message printed from this command is now different, so required a few
updates too.
---
 gdb/NEWS                                      | 18 ++++++
 gdb/ada-valprint.c                            |  4 +-
 gdb/c-lang.c                                  |  2 +-
 gdb/c-valprint.c                              |  4 +-
 gdb/doc/gdb.texinfo                           | 36 +++++++++--
 gdb/language.h                                |  2 +-
 gdb/m2-lang.c                                 |  2 +-
 gdb/m2-valprint.c                             |  2 +-
 gdb/p-lang.c                                  |  2 +-
 gdb/p-valprint.c                              |  2 +-
 gdb/printcmd.c                                |  4 +-
 gdb/python/py-value.c                         |  6 +-
 gdb/testsuite/gdb.ada/str_chars.exp           | 64 +++++++++++++++++++
 gdb/testsuite/gdb.ada/str_chars/foo.adb       | 26 ++++++++
 gdb/testsuite/gdb.base/default.exp            |  4 +-
 gdb/testsuite/gdb.base/examine-backward.exp   |  6 ++
 gdb/testsuite/gdb.base/options.exp            |  1 +
 gdb/testsuite/gdb.base/printcmds.exp          | 28 ++++----
 gdb/testsuite/gdb.base/wchar.exp              |  6 +-
 gdb/testsuite/gdb.base/with.exp               |  2 +-
 gdb/testsuite/gdb.guile/scm-pretty-print.exp  | 12 ++--
 gdb/testsuite/gdb.pascal/str-chars.exp        | 48 ++++++++++++++
 gdb/testsuite/gdb.pascal/str-chars.pas        | 28 ++++++++
 gdb/testsuite/gdb.python/py-format-string.exp | 13 ++--
 gdb/testsuite/gdb.python/py-prettyprint.exp   |  8 ++-
 gdb/testsuite/lib/gdb.exp                     |  2 +-
 gdb/tracepoint.c                              |  4 +-
 gdb/valprint.c                                | 51 +++++++++++----
 gdb/valprint.h                                |  3 +
 29 files changed, 321 insertions(+), 69 deletions(-)
 create mode 100644 gdb/testsuite/gdb.ada/str_chars.exp
 create mode 100644 gdb/testsuite/gdb.ada/str_chars/foo.adb
 create mode 100644 gdb/testsuite/gdb.pascal/str-chars.exp
 create mode 100644 gdb/testsuite/gdb.pascal/str-chars.pas

-- 
2.25.4

Comments

Lancelot SIX via Gdb-patches Oct. 7, 2021, 1:38 p.m. | #1
> From: Andrew Burgess <andrew.burgess@embecosm.com>

> Date: Thu,  7 Oct 2021 14:14:51 +0100

> 

>  gdb/NEWS                                      | 18 ++++++

>  gdb/ada-valprint.c                            |  4 +-

>  gdb/c-lang.c                                  |  2 +-

>  gdb/c-valprint.c                              |  4 +-

>  gdb/doc/gdb.texinfo                           | 36 +++++++++--

>  gdb/language.h                                |  2 +-

>  gdb/m2-lang.c                                 |  2 +-

>  gdb/m2-valprint.c                             |  2 +-

>  gdb/p-lang.c                                  |  2 +-

>  gdb/p-valprint.c                              |  2 +-

>  gdb/printcmd.c                                |  4 +-

>  gdb/python/py-value.c                         |  6 +-

>  gdb/testsuite/gdb.ada/str_chars.exp           | 64 +++++++++++++++++++

>  gdb/testsuite/gdb.ada/str_chars/foo.adb       | 26 ++++++++

>  gdb/testsuite/gdb.base/default.exp            |  4 +-

>  gdb/testsuite/gdb.base/examine-backward.exp   |  6 ++

>  gdb/testsuite/gdb.base/options.exp            |  1 +

>  gdb/testsuite/gdb.base/printcmds.exp          | 28 ++++----

>  gdb/testsuite/gdb.base/wchar.exp              |  6 +-

>  gdb/testsuite/gdb.base/with.exp               |  2 +-

>  gdb/testsuite/gdb.guile/scm-pretty-print.exp  | 12 ++--

>  gdb/testsuite/gdb.pascal/str-chars.exp        | 48 ++++++++++++++

>  gdb/testsuite/gdb.pascal/str-chars.pas        | 28 ++++++++

>  gdb/testsuite/gdb.python/py-format-string.exp | 13 ++--

>  gdb/testsuite/gdb.python/py-prettyprint.exp   |  8 ++-

>  gdb/testsuite/lib/gdb.exp                     |  2 +-

>  gdb/tracepoint.c                              |  4 +-

>  gdb/valprint.c                                | 51 +++++++++++----

>  gdb/valprint.h                                |  3 +

>  29 files changed, 321 insertions(+), 69 deletions(-)

>  create mode 100644 gdb/testsuite/gdb.ada/str_chars.exp

>  create mode 100644 gdb/testsuite/gdb.ada/str_chars/foo.adb

>  create mode 100644 gdb/testsuite/gdb.pascal/str-chars.exp

>  create mode 100644 gdb/testsuite/gdb.pascal/str-chars.pas


The documentation parts are okay, with one comment: you say
"characters", but the code actually limits the number of bytes, not
characters, right?

Thanks.

Patch

diff --git a/gdb/NEWS b/gdb/NEWS
index 7ca1f842cb1..626fd66a68b 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -32,6 +32,24 @@  maint show internal-warning backtrace
   internal-error, or an internal-warning.  This is on by default for
   internal-error and off by default for internal-warning.
 
+set print characters LIMIT
+show print characters
+print -characters LIMIT
+  This new setting is like 'set print elements', but controls how many
+  characters of a string are printed.  This functionality used to be
+  covered by 'set print elements', but is now a separate setting.
+  LIMIT can be set to 'unlimited' to print all characters of a string.
+  The default value for LIMIT is 200.
+
+* Changed commands
+
+set print elements LIMIT
+show print elements
+print -elements LIMIT
+  This setting no longer affects how many characters of a string are
+  printed, instead the new 'set print characters' setting should be
+  used.
+
 * Python API
 
   ** New function gdb.add_history(), which takes a gdb.Value object
diff --git a/gdb/ada-valprint.c b/gdb/ada-valprint.c
index e725cd3276e..1c3fff7b836 100644
--- a/gdb/ada-valprint.c
+++ b/gdb/ada-valprint.c
@@ -459,7 +459,7 @@  printstr (struct ui_file *stream, struct type *elttype, const gdb_byte *string,
       return;
     }
 
-  for (i = 0; i < length && things_printed < options->print_max; i += 1)
+  for (i = 0; i < length && things_printed < options->print_smax; i += 1)
     {
       /* Position of the character we are examining
 	 to see whether it is repeated.  */
@@ -700,7 +700,7 @@  ada_val_print_string (struct type *type, const gdb_byte *valaddr,
       /* Look for a NULL char.  */
       for (temp_len = 0;
 	   (temp_len < len
-	    && temp_len < options->print_max
+	    && temp_len < options->print_smax
 	    && char_at (valaddr + offset_aligned,
 			temp_len, eltlen, byte_order) != 0);
 	   temp_len += 1);
diff --git a/gdb/c-lang.c b/gdb/c-lang.c
index 98250f5151d..afbfb8de58a 100644
--- a/gdb/c-lang.c
+++ b/gdb/c-lang.c
@@ -185,7 +185,7 @@  language_defn::printchar (int c, struct type *type,
 /* Print the character string STRING, printing at most LENGTH
    characters.  LENGTH is -1 if the string is nul terminated.  Each
    character is WIDTH bytes long.  Printing stops early if the number
-   hits print_max; repeat counts are printed as appropriate.  Print
+   hits print_smax; repeat counts are printed as appropriate.  Print
    ellipses at the end if we had to stop before printing LENGTH
    characters, or if FORCE_ELLIPSES.  */
 
diff --git a/gdb/c-valprint.c b/gdb/c-valprint.c
index d3071d1f5b9..18a38db5706 100644
--- a/gdb/c-valprint.c
+++ b/gdb/c-valprint.c
@@ -271,7 +271,7 @@  c_value_print_array (struct value *val,
 
 	      for (temp_len = 0;
 		   (temp_len < len
-		    && temp_len < options->print_max
+		    && temp_len < options->print_smax
 		    && extract_unsigned_integer (valaddr + temp_len * eltlen,
 						 eltlen, byte_order) != 0);
 		   ++temp_len)
@@ -280,7 +280,7 @@  c_value_print_array (struct value *val,
 	      /* Force LA_PRINT_STRING to print ellipses if
 		 we've printed the maximum characters and
 		 the next character is not \000.  */
-	      if (temp_len == options->print_max && temp_len < len)
+	      if (temp_len == options->print_smax && temp_len < len)
 		{
 		  ULONGEST ival
 		    = extract_unsigned_integer (valaddr + temp_len * eltlen,
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index a6f207a41a7..a92727bb3f1 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -9994,10 +9994,15 @@ 
 Set printing of array indexes.
 Related setting: @ref{set print array-indexes}.
 
+@item -characters @var{number-of-characters}|@code{unlimited}
+Set limit on string character to print.  The value @code{unlimited}
+causes there to be no limit.  Related setting: @ref{set print
+characters}.
+
 @item -elements @var{number-of-elements}|@code{unlimited}
-Set limit on string chars or array elements to print.  The value
-@code{unlimited} causes there to be no limit.  Related setting:
-@ref{set print elements}.
+Set limit on array elements to print.  The value @code{unlimited}
+causes there to be no limit.  Related setting: @ref{set print
+elements}.
 
 @item -max-depth @var{depth}|@code{unlimited}
 Set the threshold after which nested structures are replaced with
@@ -11361,6 +11366,23 @@ 
 Show whether the index of each element is printed when displaying
 arrays.
 
+@anchor{set print characters}
+@item set print characters @var{number-of-characters}
+@itemx set print characters unlimited
+@cindex number of string characters to print
+@cindex limit on number of printed string characters
+Set a limit on how many characters of a string @value{GDBN} will
+print.  If @value{GDBN} is printing a large string, it stops printing
+after it has printed the number of characters set by the @code{set
+print characters} command.
+When @value{GDBN} starts, this limit is set to 200.
+Setting @var{number-of-characters} to @code{unlimited} or zero means
+that the number of characters to print is unlimited.
+
+@item show print characters
+Display the number of characters of a large string that @value{GDBN}
+will print.
+
 @anchor{set print elements}
 @item set print elements @var{number-of-elements}
 @itemx set print elements unlimited
@@ -11369,13 +11391,13 @@ 
 Set a limit on how many elements of an array @value{GDBN} will print.
 If @value{GDBN} is printing a large array, it stops printing after it has
 printed the number of elements set by the @code{set print elements} command.
-This limit also applies to the display of strings.
 When @value{GDBN} starts, this limit is set to 200.
 Setting @var{number-of-elements} to @code{unlimited} or zero means
 that the number of elements to print is unlimited.
 
 @item show print elements
-Display the number of elements of a large array that @value{GDBN} will print.
+Display the number of elements of a large array that @value{GDBN} will
+print.
 
 @anchor{set print frame-arguments}
 @item set print frame-arguments @var{value}
@@ -14872,7 +14894,7 @@ 
 @code{s} requests that pointers to chars be handled as strings, in
 particular collecting the contents of the memory being pointed at, up
 to the first zero.  The upper bound is by default the value of the
-@code{print elements} variable; if @code{s} is followed by a decimal
+@code{print characters} variable; if @code{s} is followed by a decimal
 number, that is the upper bound instead.  So for instance
 @samp{collect/s25 mystr} collects as many as 25 characters at
 @samp{mystr}.
@@ -27878,7 +27900,7 @@ 
 (gdb) alias -a show print elms = show print elements
 (gdb) set p elms 20
 (gdb) show p elms
-Limit on string chars or array elements to print is 200.
+Limit on array elements to print is 200.
 @end smallexample
 
 Note that if you are defining an alias of a @samp{set} command,
diff --git a/gdb/language.h b/gdb/language.h
index 1ba0b9377e2..7aee1e5f36f 100644
--- a/gdb/language.h
+++ b/gdb/language.h
@@ -534,7 +534,7 @@  struct language_defn
 			  struct ui_file * stream) const;
 
 /* Print the character string STRING, printing at most LENGTH characters.
-   Printing stops early if the number hits print_max; repeat counts
+   Printing stops early if the number hits print_smax; repeat counts
    are printed as appropriate.  Print ellipses at the end if we
    had to stop before printing LENGTH characters, or if FORCE_ELLIPSES.  */
 
diff --git a/gdb/m2-lang.c b/gdb/m2-lang.c
index 911d67d8672..949a4dbc2d4 100644
--- a/gdb/m2-lang.c
+++ b/gdb/m2-lang.c
@@ -169,7 +169,7 @@  m2_language::printstr (struct ui_file *stream, struct type *elttype,
       return;
     }
 
-  for (i = 0; i < length && things_printed < options->print_max; ++i)
+  for (i = 0; i < length && things_printed < options->print_smax; ++i)
     {
       /* Position of the character we are examining
 	 to see whether it is repeated.  */
diff --git a/gdb/m2-valprint.c b/gdb/m2-valprint.c
index be21cbb014a..25007847097 100644
--- a/gdb/m2-valprint.c
+++ b/gdb/m2-valprint.c
@@ -332,7 +332,7 @@  m2_language::value_print_inner (struct value *val, struct ui_file *stream,
 		  /* Look for a NULL char.  */
 		  for (temp_len = 0;
 		       (valaddr[temp_len]
-			&& temp_len < len && temp_len < options->print_max);
+			&& temp_len < len && temp_len < options->print_smax);
 		       temp_len++);
 		  len = temp_len;
 		}
diff --git a/gdb/p-lang.c b/gdb/p-lang.c
index cac8fbeaeb0..28e555c95b7 100644
--- a/gdb/p-lang.c
+++ b/gdb/p-lang.c
@@ -253,7 +253,7 @@  pascal_language::printstr (struct ui_file *stream, struct type *elttype,
       return;
     }
 
-  for (i = 0; i < length && things_printed < options->print_max; ++i)
+  for (i = 0; i < length && things_printed < options->print_smax; ++i)
     {
       /* Position of the character we are examining
 	 to see whether it is repeated.  */
diff --git a/gdb/p-valprint.c b/gdb/p-valprint.c
index 44be49848b2..dd6333540f4 100644
--- a/gdb/p-valprint.c
+++ b/gdb/p-valprint.c
@@ -111,7 +111,7 @@  pascal_language::value_print_inner (struct value *val,
 		    for (temp_len = 0;
 			 extract_unsigned_integer (valaddr + temp_len * eltlen,
 						   eltlen, byte_order)
-			   && temp_len < len && temp_len < options->print_max;
+			   && temp_len < len && temp_len < options->print_smax;
 			 temp_len++);
 		    len = temp_len;
 		  }
diff --git a/gdb/printcmd.c b/gdb/printcmd.c
index 2fe3f4b0cc5..ac42bfc93ed 100644
--- a/gdb/printcmd.c
+++ b/gdb/printcmd.c
@@ -968,9 +968,9 @@  find_string_backward (struct gdbarch *gdbarch,
 	  int offset = (chars_to_read - i - 1) * char_size;
 
 	  if (integer_is_zero (&buffer[offset], char_size)
-	      || chars_counted == options->print_max)
+	      || chars_counted == options->print_smax)
 	    {
-	      /* Found '\0' or reached print_max.  As OFFSET is the offset to
+	      /* Found '\0' or reached print_smax.  As OFFSET is the offset to
 		 '\0', we add CHAR_SIZE to return the start address of
 		 a string.  */
 	      --count;
diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c
index d45df5fd113..98b5cceed3f 100644
--- a/gdb/python/py-value.c
+++ b/gdb/python/py-value.c
@@ -623,6 +623,7 @@  valpy_format_string (PyObject *self, PyObject *args, PyObject *kw)
       "actual_objects",		/* See set print object on|off.  */
       "static_members",		/* See set print static-members on|off.  */
       /* C non-bool options.  */
+      "max_characters", 	/* See set print elements N.  */
       "max_elements", 		/* See set print elements N.  */
       "max_depth",		/* See set print max-depth N.  */
       "repeat_threshold",	/* See set print repeats.  */
@@ -668,7 +669,7 @@  valpy_format_string (PyObject *self, PyObject *args, PyObject *kw)
   char *format = NULL;
   if (!gdb_PyArg_ParseTupleAndKeywords (args,
 					kw,
-					"|O!O!O!O!O!O!O!O!O!O!IIIs",
+					"|O!O!O!O!O!O!O!O!O!O!IIIIs",
 					keywords,
 					&PyBool_Type, &raw_obj,
 					&PyBool_Type, &pretty_arrays_obj,
@@ -680,6 +681,7 @@  valpy_format_string (PyObject *self, PyObject *args, PyObject *kw)
 					&PyBool_Type, &deref_refs_obj,
 					&PyBool_Type, &actual_objects_obj,
 					&PyBool_Type, &static_members_obj,
+					&opts.print_smax,
 					&opts.print_max,
 					&opts.max_depth,
 					&opts.repeat_count_threshold,
@@ -713,6 +715,8 @@  valpy_format_string (PyObject *self, PyObject *args, PyObject *kw)
      unlimited, and 0 is a valid choice.  */
   if (opts.print_max == 0)
     opts.print_max = UINT_MAX;
+  if (opts.print_smax == 0)
+    opts.print_smax = UINT_MAX;
   if (opts.repeat_count_threshold == 0)
     opts.repeat_count_threshold = UINT_MAX;
 
diff --git a/gdb/testsuite/gdb.ada/str_chars.exp b/gdb/testsuite/gdb.ada/str_chars.exp
new file mode 100644
index 00000000000..a7f0ec792e4
--- /dev/null
+++ b/gdb/testsuite/gdb.ada/str_chars.exp
@@ -0,0 +1,64 @@ 
+# Copyright 2021 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# Test GDB's 'set print characters' setting works for Ada strings.
+
+load_lib "ada.exp"
+
+if { [skip_ada_tests] } { return -1 }
+
+standard_ada_testfile foo
+
+if {[gdb_compile_ada "${srcfile}" "${binfile}" executable [list debug ]] != "" } {
+  return -1
+}
+
+clean_restart ${testfile}
+
+set bp_location [gdb_get_line_number "STOP" ${testdir}/foo.adb]
+if ![runto "foo.adb:$bp_location" ] then {
+  return -1
+}
+
+gdb_test "print Arg" \
+    " = \"abcdefghijklmnopqrstuvwxyz\"" \
+    "print with default settings"
+
+gdb_test_no_output "set print characters 26"
+gdb_test "print Arg" \
+    " = \"abcdefghijklmnopqrstuvwxyz\"" \
+    "print with character limit of 26"
+
+gdb_test "print -characters 11 -- Arg" \
+    " = \"abcdefghijk\"\\.\\.\\." \
+    "print with character limit of 11"
+
+gdb_test_no_output "set print characters 10"
+gdb_test "print Arg" \
+    " = \"abcdefghij\"\\.\\.\\." \
+    "print with character limit of 10"
+
+gdb_test_no_output "set print characters unlimited"
+gdb_test "print Arg" \
+    " = \"abcdefghijklmnopqrstuvwxyz\"" \
+    "print with unlimited character limit"
+
+# The 'set print elements' used to control printing of characters in a
+# string, before we created 'set print characters'.  This test ensures
+# that 'set print elements' doens't effect string printing any more.
+gdb_test_no_output "set print elements 10"
+gdb_test "print Arg" \
+    " = \"abcdefghijklmnopqrstuvwxyz\"" \
+    "print with unlimited character limit, but lower element limit"
diff --git a/gdb/testsuite/gdb.ada/str_chars/foo.adb b/gdb/testsuite/gdb.ada/str_chars/foo.adb
new file mode 100644
index 00000000000..e5a66cca700
--- /dev/null
+++ b/gdb/testsuite/gdb.ada/str_chars/foo.adb
@@ -0,0 +1,26 @@ 
+--  Copyright 2021 Free Software Foundation, Inc.
+--
+--  This program is free software; you can redistribute it and/or modify
+--  it under the terms of the GNU General Public License as published by
+--  the Free Software Foundation; either version 3 of the License, or
+--  (at your option) any later version.
+--
+--  This program is distributed in the hope that it will be useful,
+--  but WITHOUT ANY WARRANTY; without even the implied warranty of
+--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+--  GNU General Public License for more details.
+--
+--  You should have received a copy of the GNU General Public License
+--  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+procedure Foo is
+
+   procedure Blah (Arg : String) is
+   begin
+     null; -- STOP
+   end;
+
+begin
+
+   Blah ("abcdefghijklmnopqrstuvwxyz");
+end Foo;
diff --git a/gdb/testsuite/gdb.base/default.exp b/gdb/testsuite/gdb.base/default.exp
index e32b769478c..9a753529f64 100644
--- a/gdb/testsuite/gdb.base/default.exp
+++ b/gdb/testsuite/gdb.base/default.exp
@@ -667,7 +667,7 @@  gdb_test "show print asm-demangle" "Demangling of C\[+\]+/ObjC names in disassem
 #test show print demangle
 gdb_test "show print demangle" "Demangling of encoded C\[+\]+/ObjC names when displaying symbols is on."
 #test show print elements
-gdb_test "show print elements" "Limit on string chars or array elements to print is 200."
+gdb_test "show print elements" "Limit on array elements to print is 200."
 #test show print object
 gdb_test "show print object" "Printing of object's derived type based on vtable info is on."
 #test show print pretty
@@ -702,7 +702,7 @@  gdb_test "show write" "Writing into executable and core files is o.*"
 set show_confirm_seen 0
 set show_prompt_seen 0
 gdb_test_multiple "show" "show" {
-    -re "confirm:  *Whether to confirm potentially dangerous operations is on.(\[^\r\n\]*\[\r\n\])+history filename:  *The filename in which to record the command history is (\[^\r\n\]*\[\r\n\])+history save:  *Saving of the history record on exit is on.(\[^\r\n\]*\[\r\n\])+history size:  *The size of the command history is(\[^\r\n\]*\[\r\n\])+listsize:  *Number of source lines gdb will list by default is 10(\[^\r\n]*\[\r\n\])+print elements:  *Limit on string chars or array elements to print is 200." {
+    -re "confirm:  *Whether to confirm potentially dangerous operations is on.(\[^\r\n\]*\[\r\n\])+history filename:  *The filename in which to record the command history is (\[^\r\n\]*\[\r\n\])+history save:  *Saving of the history record on exit is on.(\[^\r\n\]*\[\r\n\])+history size:  *The size of the command history is(\[^\r\n\]*\[\r\n\])+listsize:  *Number of source lines gdb will list by default is 10(\[^\r\n]*\[\r\n\])+print elements:  *Limit on array elements to print is 200." {
 	verbose "Confirm dislayed"
 	set show_confirm_seen 1
 	exp_continue
diff --git a/gdb/testsuite/gdb.base/examine-backward.exp b/gdb/testsuite/gdb.base/examine-backward.exp
index d4ad4a67ad1..172959c3f35 100644
--- a/gdb/testsuite/gdb.base/examine-backward.exp
+++ b/gdb/testsuite/gdb.base/examine-backward.exp
@@ -56,6 +56,7 @@  with_test_prefix "memory page boundary" {
     set boundary [get_first_mapped_address]
     if {![is_address_zero_readable] && $boundary != 0} {
         gdb_test_no_output "set print elements 0"
+        gdb_test_no_output "set print characters 0"
         gdb_test_sequence "x/3s ${boundary}" "take 3 strings forward" {
             "0x"
             "0x"
@@ -145,6 +146,7 @@  gdb_test_no_output "set charset ASCII"
 
 with_test_prefix "char-width=1, print-max=20" {
     gdb_test_no_output "set print elements 20"
+    gdb_test_no_output "set print characters 20"
     gdb_test_sequence "x/6s &TestStrings" "take 6 strings forward" {
         "\"ABCDEFGHIJKLMNOPQRST\"\.\.\."
         "\"UVWXYZ\""
@@ -187,6 +189,7 @@  with_test_prefix "char-width=1, print-max=20" {
 
 with_test_prefix "char-width=2, print-max=20" {
     gdb_test_no_output "set print elements 20"
+    gdb_test_no_output "set print characters 20"
     gdb_test_sequence "x/6sh &TestStringsH" "take 6 strings forward" {
         "u\"ABCDEFGHIJKLMNOPQRST\"\.\.\."
         "u\"UVWXYZ\""
@@ -229,6 +232,7 @@  with_test_prefix "char-width=2, print-max=20" {
 
 with_test_prefix "char-width=4, print-max=20" {
     gdb_test_no_output "set print elements 20"
+    gdb_test_no_output "set print characters 20"
     gdb_test_sequence "x/6sw &TestStringsW" "take 6 strings forward" {
         "U\"ABCDEFGHIJKLMNOPQRST\"\.\.\."
         "U\"UVWXYZ\""
@@ -271,6 +275,7 @@  with_test_prefix "char-width=4, print-max=20" {
 
 with_test_prefix "char-width=2, print-max=0" {
     gdb_test_no_output "set print elements 0"
+    gdb_test_no_output "set print characters 0"
     gdb_test_sequence "x/6sh &TestStringsH" "take 6 strings forward" {
         "u\"ABCDEFGHIJKLMNOPQRSTUVWXYZ\""
         "u\"\""
@@ -314,6 +319,7 @@  with_test_prefix "char-width=2, print-max=0" {
 
 with_test_prefix "char-width=1, print-max=4" {
     gdb_test_no_output "set print elements 4"
+    gdb_test_no_output "set print characters 4"
     gdb_test_sequence "x/9s &TestStrings" "take 9 strings forward" {
         "\"ABCD\"\.\.\."
         "\"EFGH\"\.\.\."
diff --git a/gdb/testsuite/gdb.base/options.exp b/gdb/testsuite/gdb.base/options.exp
index 94372aa9fc7..f2a0072ac81 100644
--- a/gdb/testsuite/gdb.base/options.exp
+++ b/gdb/testsuite/gdb.base/options.exp
@@ -165,6 +165,7 @@  proc_with_prefix test-print {{prefix ""}} {
 	"-address"
 	"-array"
 	"-array-indexes"
+	"-characters"
 	"-elements"
 	"-max-depth"
 	"-memory-tag-violations"
diff --git a/gdb/testsuite/gdb.base/printcmds.exp b/gdb/testsuite/gdb.base/printcmds.exp
index b2f90aaff10..fdbe36ec2c1 100644
--- a/gdb/testsuite/gdb.base/printcmds.exp
+++ b/gdb/testsuite/gdb.base/printcmds.exp
@@ -438,7 +438,7 @@  proc test_print_repeats_10 {} {
     global gdb_prompt decimal
 
     for { set x 1 } { $x <= 16 } { incr x } {
-	gdb_test_no_output "set print elements $x" "elements $x repeats"
+	gdb_test_no_output "set print characters $x" "set print characters $x repeats"
 	for { set e 1 } { $e <= 16 } {incr e } {
 	    set v [expr $e - 1]
 	    set command "p &ctable2\[${v}*16\]"
@@ -478,7 +478,7 @@  proc test_print_repeats_10 {} {
 		set xstr "${xstr}\[.\]\[.\]\[.\]"
 	    }
 	    set string " = \[(\]unsigned char \[*\]\[)\] <ctable2(\\+$decimal)?> ${a}${xstr}"
-	    gdb_test "$command" "$string" "$command with print elements set to $x"
+	    gdb_test "$command" "$string" "$command with print characters set to $x"
 	}
     }
 }
@@ -503,26 +503,26 @@  proc test_print_strings {} {
 
     # Test that setting print elements unlimited doesn't completely suppress
     # printing; this was a bug in older gdb's.
-    gdb_test_no_output "set print elements 0"
+    gdb_test_no_output "set print characters 0"
     gdb_test "p teststring" \
-	" = (.unsigned char .. )?\"teststring contents\"" "p teststring with elements set to 0"
-    gdb_test_no_output "set print elements 1"
+	" = (.unsigned char .. )?\"teststring contents\"" "p teststring with characters set to 0"
+    gdb_test_no_output "set print characters 1"
     gdb_test "p teststring" \
-	" = (.unsigned char .. )?\"t\"\\.\\.\\." "p teststring with elements set to 1"
-    gdb_test_no_output "set print elements 5"
+	" = (.unsigned char .. )?\"t\"\\.\\.\\." "p teststring with characters set to 1"
+    gdb_test_no_output "set print characters 5"
     gdb_test "p teststring" \
-	" = (.unsigned char .. )?\"tests\"\\.\\.\\." "p teststring with elements set to 5"
-    gdb_test_no_output "set print elements 19"
+	" = (.unsigned char .. )?\"tests\"\\.\\.\\." "p teststring with characters set to 5"
+    gdb_test_no_output "set print characters 19"
     gdb_test "p teststring" \
-	" = (.unsigned char .. )?\"teststring contents\"" "p teststring with elements set to 19"
-    gdb_test_no_output "set print elements 20"
+	" = (.unsigned char .. )?\"teststring contents\"" "p teststring with characters set to 19"
+    gdb_test_no_output "set print characters 20"
     gdb_test "p teststring" \
-	" = (.unsigned char .. )?\"teststring contents\"" "p teststring with elements set to 20"
+	" = (.unsigned char .. )?\"teststring contents\"" "p teststring with characters set to 20"
 
     gdb_test "print teststring2" \
 	" = \\(charptr\\) \"more contents\""
 
-    gdb_test_no_output "set print elements 8"
+    gdb_test_no_output "set print characters 8"
 
     # Set the target-charset to ASCII, because the output varies from
     # different charset.
@@ -693,7 +693,7 @@  proc test_print_char_arrays {} {
 proc test_print_string_constants {} {
     global gdb_prompt
 
-    gdb_test_no_output "set print elements 50"
+    gdb_test_no_output "set print characters 50"
 
     if [target_info exists gdb,cannot_call_functions] {
 	unsupported "this target can not call functions"
diff --git a/gdb/testsuite/gdb.base/wchar.exp b/gdb/testsuite/gdb.base/wchar.exp
index f98351b0cfc..b6dbd4a35c2 100644
--- a/gdb/testsuite/gdb.base/wchar.exp
+++ b/gdb/testsuite/gdb.base/wchar.exp
@@ -62,13 +62,13 @@  gdb_test_no_output "set print null on"
 gdb_test "print repeat" "= L\"A\", '$cent' <repeats 21 times>, \"B\"" \
     "print repeat (print null on)"
 
-gdb_test_no_output "set print elements 3"
+gdb_test_no_output "set print characters 3"
 
 gdb_test "print repeat" "= L\"A$cent$cent\"\.\.\." \
-    "print repeat (print elements 3)"
+    "print repeat (print characters 3)"
 
 gdb_test "print repeat_p" "= $hex L\"A$cent$cent\"\.\.\." \
-    "print repeat_p (print elements 3)"
+    "print repeat_p (print characters 3)"
 
 # From PR cli/14977, but here because it requires wchar_t.
 gdb_test "printf \"%ls\\n\", 0" "\\(null\\)"
diff --git a/gdb/testsuite/gdb.base/with.exp b/gdb/testsuite/gdb.base/with.exp
index 3a21ab8868a..00f54c91c05 100644
--- a/gdb/testsuite/gdb.base/with.exp
+++ b/gdb/testsuite/gdb.base/with.exp
@@ -252,7 +252,7 @@  with_test_prefix "errors" {
     gdb_test "with print elements 1 -- unknowncommand" \
 	"Undefined command: \"unknowncommand\"\\.  Try \"help\"\\."
     gdb_test "show print elements" \
-	"Limit on string chars or array elements to print is 200\\."
+	"Limit on array elements to print is 200\\."
 }
 
 # Check completion.
diff --git a/gdb/testsuite/gdb.guile/scm-pretty-print.exp b/gdb/testsuite/gdb.guile/scm-pretty-print.exp
index 00229efd806..0ef3f161c52 100644
--- a/gdb/testsuite/gdb.guile/scm-pretty-print.exp
+++ b/gdb/testsuite/gdb.guile/scm-pretty-print.exp
@@ -76,13 +76,15 @@  proc run_lang_tests {exefile lang} {
 		" = \{.*<Vbase1> = pp class name: Vbase1.*<Vbase2> = \{.*<VirtualTest> = pp value variable is: 1,.*members of Vbase2:.*_vptr.Vbase2 = $hex.*<Vbase3> = \{.*members of Vbase3.*members of Derived:.*value = 2.*"
 	    gdb_test "print ns " "\"embedded\\\\000null\\\\000string\"" \
 		"print ns with 200 elements"
-	    gdb_test_no_output "set print elements 3" ""
+	    gdb_test_no_output "set print characters 3" ""
 	    gdb_test "print ns" "emb\.\.\.." \
-		"print ns with 3 elements"
-	    gdb_test_no_output "set print elements 10" ""
+		"print ns with 3 characters"
+	    gdb_test "print -characters 4 -- ns" "embe\.\.\.." \
+		"print ns with 4 characters"
+	    gdb_test_no_output "set print characters 10" ""
 	    gdb_test "print ns" "embedded\\\\000n\.\.\.." \
-		"print ns with 10 elements"
-	    gdb_test_no_output "set print elements 200" ""
+		"print ns with 10 characters"
+	    gdb_test_no_output "set print characters 200" ""
 	}
 
 	if { ![is_address_zero_readable] } {
diff --git a/gdb/testsuite/gdb.pascal/str-chars.exp b/gdb/testsuite/gdb.pascal/str-chars.exp
new file mode 100644
index 00000000000..65310583118
--- /dev/null
+++ b/gdb/testsuite/gdb.pascal/str-chars.exp
@@ -0,0 +1,48 @@ 
+# Copyright 2021 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+load_lib "pascal.exp"
+
+standard_testfile .pas
+
+if {[gdb_compile_pascal "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug ]] != "" } {
+  return -1
+}
+
+clean_restart ${testfile}
+gdb_breakpoint ${srcfile}:[gdb_get_line_number "set breakpoint 1 here"]
+
+# Verify that "start" lands inside the right procedure.
+if { [gdb_start_cmd] < 0 } {
+    untested start
+    return -1
+}
+
+gdb_continue_to_breakpoint "continue to breakpoint"
+
+gdb_test "print message" " = 'abcdefghijklmnopqrstuvwxyz'" \
+    "print message with the default settings"
+
+gdb_test_no_output "set print elements 10"
+gdb_test "print message" " = 'abcdefghijklmnopqrstuvwxyz'" \
+    "print message with 'print elements' set to 10"
+
+gdb_test_no_output "set print characters 10"
+gdb_test "print message" " = 'abcdefghij'\\.\\.\\." \
+    "print message with 'print characters' set to 10"
+
+gdb_test_no_output "set print characters unlimited"
+gdb_test "print message" " = 'abcdefghijklmnopqrstuvwxyz'" \
+    "print message with 'print characters' set to unlimited"
diff --git a/gdb/testsuite/gdb.pascal/str-chars.pas b/gdb/testsuite/gdb.pascal/str-chars.pas
new file mode 100644
index 00000000000..22ef25a2063
--- /dev/null
+++ b/gdb/testsuite/gdb.pascal/str-chars.pas
@@ -0,0 +1,28 @@ 
+{
+ Copyright 2021 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program.  If not, see <http://www.gnu.org/licenses/>.
+}
+
+program str_char;
+
+var
+   message : string;
+
+begin
+
+   message := 'abcdefghijklmnopqrstuvwxyz';
+   writeln (message)	{ set breakpoint 1 here }
+
+end.
diff --git a/gdb/testsuite/gdb.python/py-format-string.exp b/gdb/testsuite/gdb.python/py-format-string.exp
index ea5e958b17d..d4bf5d9d696 100644
--- a/gdb/testsuite/gdb.python/py-format-string.exp
+++ b/gdb/testsuite/gdb.python/py-format-string.exp
@@ -632,7 +632,7 @@  proc_with_prefix test_max_elements {} {
 
   # 200 is the default maximum number of elements, so setting it should
   # not change the output.
-  set opts "max_elements=200"
+  set opts "max_elements=200, max_characters=200"
   with_test_prefix $opts {
     check_format_string "a_point_t" $opts
     check_format_string "a_point_t_pointer" $opts
@@ -653,7 +653,7 @@  proc_with_prefix test_max_elements {} {
     }
   }
 
-  set opts "max_elements=3"
+  set opts "max_elements=3, max_characters=3"
   with_test_prefix $opts {
     check_format_string "a_point_t" $opts
     check_format_string "a_point_t_pointer" $opts
@@ -683,7 +683,7 @@  proc_with_prefix test_max_elements {} {
 
   # Both 1,000 (we don't have that many elements) and 0 (unlimited) should
   # mean no truncation.
-  foreach opts { "max_elements=1000" "max_elements=0" } {
+  foreach opts { "max_elements=1000, max_characters=1000" "max_elements=0, max_characters=0" } {
     with_test_prefix $opts {
       check_format_string "a_point_t" $opts
       check_format_string "a_point_t_pointer" $opts
@@ -706,13 +706,16 @@  proc_with_prefix test_max_elements {} {
     }
   }
 
-  with_temp_option "set print elements 4" "set print elements 200" {
+  with_temp_option "set print characters 4" "set print characters 200" {
     check_format_string "a_string" "" \
       "${default_pointer_regexp} \"hell\"..."
     check_format_string "a_binary_string" "" \
       "${default_pointer_regexp} \"hell\"..."
     check_format_string "a_binary_string_array" "" \
-      "\"hell\"..."
+	"\"hell\"..."
+  }
+
+  with_temp_option "set print elements 4" "set print elements 200" {
     check_format_string "an_array_with_repetition" "" \
       "\\{1, 3 <repeats 12 times>...\\}"
   }
diff --git a/gdb/testsuite/gdb.python/py-prettyprint.exp b/gdb/testsuite/gdb.python/py-prettyprint.exp
index 1a5b43fcf28..6790548eac4 100644
--- a/gdb/testsuite/gdb.python/py-prettyprint.exp
+++ b/gdb/testsuite/gdb.python/py-prettyprint.exp
@@ -80,13 +80,15 @@  proc run_lang_tests {exefile lang} {
 	    " = \{.*<Vbase1> = pp class name: Vbase1.*<Vbase2> = \{.*<VirtualTest> = pp value variable is: 1,.*members of Vbase2:.*_vptr.Vbase2 = $hex.*<Vbase3> = \{.*members of Vbase3.*members of Derived:.*value = 2.*"
 	gdb_test "print ns " "\"embedded\\\\000null\\\\000string\"" \
 	    "print ns with default element limit"
-	gdb_test_no_output "set print elements 3"
+	gdb_test_no_output "set print characters 3"
 	gdb_test "print ns" "emb\.\.\.." \
 	    "print ns with element limit of 3"
-	gdb_test_no_output "set print elements 10"
+	gdb_test "print -characters 4 -- ns" "embe\.\.\.." \
+	    "print ns with element limit of 4"
+	gdb_test_no_output "set print characters 10"
 	gdb_test "print ns" "embedded\\\\000n\.\.\.." \
 	    "print ns with element limit of 10"
-	gdb_test_no_output "set print elements 200"
+	gdb_test_no_output "set print characters 200"
     }
 
     if { ![is_address_zero_readable] } {
diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
index 5642db4334d..2e95a50ee4f 100644
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -6410,7 +6410,7 @@  gdb_caching_proc gdb_has_argv0 {
 	set old_elements "200"
 	set test "show print elements"
 	gdb_test_multiple $test $test {
-	    -re "Limit on string chars or array elements to print is (\[^\r\n\]+)\\.\r\n$gdb_prompt $" {
+	    -re "Limit on array elements to print is (\[^\r\n\]+)\\.\r\n$gdb_prompt $" {
 		set old_elements $expect_out(1,string)
 	    }
 	}
diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c
index 3997d211182..da32653d274 100644
--- a/gdb/tracepoint.c
+++ b/gdb/tracepoint.c
@@ -545,9 +545,9 @@  decode_agent_options (const char *exp, int *trace_string)
       if (target_supports_string_tracing ())
 	{
 	  /* Allow an optional decimal number giving an explicit maximum
-	     string length, defaulting it to the "print elements" value;
+	     string length, defaulting it to the "print characters" value;
 	     so "collect/s80 mystr" gets at most 80 bytes of string.  */
-	  *trace_string = opts.print_max;
+	  *trace_string = opts.print_smax;
 	  exp++;
 	  if (*exp >= '0' && *exp <= '9')
 	    *trace_string = atoi (exp);
diff --git a/gdb/valprint.c b/gdb/valprint.c
index c6ea0d82e40..62b80a57ad3 100644
--- a/gdb/valprint.c
+++ b/gdb/valprint.c
@@ -97,8 +97,11 @@  static void val_print_type_code_flags (struct type *type,
 				       int embedded_offset,
 				       struct ui_file *stream);
 
-#define PRINT_MAX_DEFAULT 200	/* Start print_max off at this value.  */
-#define PRINT_MAX_DEPTH_DEFAULT 20	/* Start print_max_depth off at this value. */
+/* Start print_max and print_smax at this value.  */
+#define PRINT_MAX_DEFAULT 200
+
+/* Start print_max_depth at this value. */
+#define PRINT_MAX_DEPTH_DEFAULT 20
 
 struct value_print_options user_print_options =
 {
@@ -110,6 +113,7 @@  struct value_print_options user_print_options =
   1,				/* addressprint */
   0,				/* objectprint */
   PRINT_MAX_DEFAULT,		/* print_max */
+  PRINT_MAX_DEFAULT,		/* print_smax */
   10,				/* repeat_count_threshold */
   0,				/* output_format */
   0,				/* format */
@@ -152,13 +156,25 @@  get_formatted_print_options (struct value_print_options *opts,
   opts->format = format;
 }
 
+/* Implement 'show print elements'.  */
+
 static void
 show_print_max (struct ui_file *file, int from_tty,
 		struct cmd_list_element *c, const char *value)
 {
   fprintf_filtered (file,
-		    _("Limit on string chars or array "
-		      "elements to print is %s.\n"),
+		    _("Limit on array elements to print is %s.\n"),
+		    value);
+}
+
+/* Implement 'show print characters'.  */
+
+static void
+show_print_smax (struct ui_file *file, int from_tty,
+		struct cmd_list_element *c, const char *value)
+{
+  fprintf_filtered (file,
+		    _("Limit on string characters to print is %s.\n"),
 		    value);
 }
 
@@ -2601,7 +2617,7 @@  print_converted_chars_to_obstack (struct obstack *obstack,
 /* Print the character string STRING, printing at most LENGTH
    characters.  LENGTH is -1 if the string is nul terminated.  TYPE is
    the type of each character.  OPTIONS holds the printing options;
-   printing stops early if the number hits print_max; repeat counts
+   printing stops early if the number hits print_smax; repeat counts
    are printed as appropriate.  Print ellipses at the end if we had to
    stop before printing LENGTH characters, or if FORCE_ELLIPSES.
    QUOTE_CHAR is the character to print at each end of the string.  If
@@ -2657,7 +2673,7 @@  generic_printstr (struct ui_file *stream, struct type *type,
   /* Convert characters until the string is over or the maximum
      number of printed characters has been reached.  */
   i = 0;
-  while (i < options->print_max)
+  while (i < options->print_smax)
     {
       int r;
 
@@ -2709,7 +2725,7 @@  generic_printstr (struct ui_file *stream, struct type *type,
 /* Print a string from the inferior, starting at ADDR and printing up to LEN
    characters, of WIDTH bytes a piece, to STREAM.  If LEN is -1, printing
    stops at the first null byte, otherwise printing proceeds (including null
-   bytes) until either print_max or LEN characters have been printed,
+   bytes) until either print_smax or LEN characters have been printed,
    whichever is smaller.  ENCODING is the name of the string's
    encoding.  It can be NULL, in which case the target encoding is
    assumed.  */
@@ -2733,13 +2749,13 @@  val_print_string (struct type *elttype, const char *encoding,
   /* First we need to figure out the limit on the number of characters we are
      going to attempt to fetch and print.  This is actually pretty simple.  If
      LEN >= zero, then the limit is the minimum of LEN and print_max.  If
-     LEN is -1, then the limit is print_max.  This is true regardless of
-     whether print_max is zero, UINT_MAX (unlimited), or something in between,
+     LEN is -1, then the limit is print_smax.  This is true regardless of
+     whether print_smax is zero, UINT_MAX (unlimited), or something in between,
      because finding the null byte (or available memory) is what actually
      limits the fetch.  */
 
-  fetchlimit = (len == -1 ? options->print_max : std::min ((unsigned) len,
-							   options->print_max));
+  fetchlimit = (len == -1 ? options->print_smax : std::min ((unsigned) len,
+							    options->print_smax));
 
   err = read_string (addr, len, width, fetchlimit, byte_order,
 		     &buffer, &bytes_read);
@@ -3020,8 +3036,17 @@  static const gdb::option::option_def value_print_option_defs[] = {
     "elements",
     [] (value_print_options *opt) { return &opt->print_max; },
     show_print_max, /* show_cmd_cb */
-    N_("Set limit on string chars or array elements to print."),
-    N_("Show limit on string chars or array elements to print."),
+    N_("Set limit on array elements to print."),
+    N_("Show limit on array elements to print."),
+    N_("\"unlimited\" causes there to be no limit."),
+  },
+
+  uinteger_option_def {
+    "characters",
+    [] (value_print_options *opt) { return &opt->print_smax; },
+    show_print_smax, /* show_cmd_cb */
+    N_("Set limit on string chars to print."),
+    N_("Show limit on string chars to print."),
     N_("\"unlimited\" causes there to be no limit."),
   },
 
diff --git a/gdb/valprint.h b/gdb/valprint.h
index e1dae2cc8fc..f58d6ba7b0e 100644
--- a/gdb/valprint.h
+++ b/gdb/valprint.h
@@ -54,6 +54,9 @@  struct value_print_options
      "unlimited".  */
   unsigned int print_max;
 
+  /* Maxiumum number of string chars to print */
+  unsigned int print_smax;
+
   /* Print repeat counts if there are more than this many repetitions
      of an element in an array.  */
   unsigned int repeat_count_threshold;