[pushed] gdb: Support printf 'z' size modifier

Andrew Burgess andrew.burgess@embecosm.com
Thu Nov 14 16:49:00 GMT 2019


* Eli Zaretskii <eliz@gnu.org> [2019-11-14 14:54:50 +0200]:

> > Date: Tue, 12 Nov 2019 18:53:15 -0500
> > From: "Sourceware to Gerrit sync (Code Review)" <gerrit@gnutoolchain-gerrit.osci.io>
> > Cc: Kevin Buettner <kevinb@redhat.com>,	Joel Brobecker <brobecker@adacore.com>,	Pedro Alves <palves@redhat.com>,	Simon Marchi <simon.marchi@polymtl.ca>,	Tom Tromey <tromey@sourceware.org>
> > 
> > gdb/ChangeLog:
> > 
> > 	* gdbsupport/format.c (format_pieces::format_pieces): Support
> > 	printf 'z' size modifier.
> > 	* gdbsupport/format.h (enum argclass): Add size_t_arg.
> > 	* printcmd.c (ui_printf):  Handle size_t_arg.
> > 	* ui-out.c (ui_out::vmessage): Likewise.
> > 	* unittests/format_pieces-selftests.c (test_format_int_sizes): New
> > 	function.
> > 	(run_tests): Call test_format_int_sizes.
> 
> I believe this requires to use __USE_MINGW_ANSI_STDIO with the MinGW
> builds, since %z is not universally supported by the Windows runtime.

I only stumbled onto this issue as I hit a use of %z (which wasn't
guarded with __USE_MINGW_ANSI_STDIO) and wanted it to work now that
these strings pass through GDB's formatting code.

I guess we're no worse off now than we were before, but obviously
that's not saying much if we were possibly broken before.

I guess there are a couple of solutions:

  1. Remove all uses of %z from GDB, and back out the %z support, or

  2. Have GDB translate %z into some other suitable format specifier
     for targets where %z is not supported.

Below is a patch that tries to take the second approach.

Feedback / thoughts welcome.

Thanks,
Andrew

----


commit fb431811b59597b63c5bb9bcf7bf8559991c52e1
Author: Andrew Burgess <andrew.burgess@embecosm.com>
Date:   Thu Nov 14 16:40:57 2019 +0000

    gdb: Support for %z format on MinGW
    
    Eli pointed out that the %z size specifier is not supported on all
    versions of MinGW.  This commit attempts to work around this by
    translating %z into some other suitable format specifier.  So
    something like %zd will become either %d, %ld, or %lld depending on
    whether the sizeof (size_t) matches the sizeof (int), sizeof (long),
    or sizeof (long long).
    
    For the long long case we might also translate to %I64d if
    USE_PRINTF_I64 is true.
    
    I don't have access to MinGW so this code is mostly untested - I did
    remove the '#if defined __MINGW32__ ....' check and try using %z in
    some formatted prints, this all seemed to work fine - on my machine
    sizeof (size_t) == sizeof (long).
    
    gdb/ChangeLog:
    
            * gdbsupport/format.c (format_pieces::format_pieces): Translate %z
            into some other suitable format size specifier if it is not
            supported.
    
    Change-Id: I20f5e4cb1a7ab88f00f5e42d3fd8ca4aef00993d

diff --git a/gdb/gdbsupport/format.c b/gdb/gdbsupport/format.c
index 2e2d90a9246..e316e840e22 100644
--- a/gdb/gdbsupport/format.c
+++ b/gdb/gdbsupport/format.c
@@ -375,6 +375,40 @@ format_pieces::format_pieces (const char **arg, bool gdb_extensions)
 	    strcpy (current_substring + length_before_ls, "s");
 	    current_substring += length_before_ls + 2;
 	  }
+#if defined __MINGW32__ && !defined __USE_MINGW_ANSI_STDIO
+	else if (this_argclass == size_t_arg)
+	  {
+	    /* Some versions of MinGW don't support the %z size format, so
+	       lets change to use some appropriate alternative.  */
+	    *current_substring++ = '%';
+	    if (sizeof (size_t) == sizeof (int))
+	      {
+		*current_substring++ = *(percent_loc + 2);
+		this_argclass = int_arg;
+	      }
+	    else if (sizeof (size_t) == sizeof (long))
+	      {
+		*current_substring++ = 'l';
+		*current_substring++ = *(percent_loc + 2);
+		this_argclass = long_arg;
+	      }
+	    else if (sizeof (size_t) == sizeof (long long))
+	      {
+		if (USE_PRINTF_I64)
+		  {
+		    strcpy (current_substring, "I64");
+		    current_substring += 3;
+		  }
+		else
+		  {
+		    strcpy (current_substring, "ll");
+		    current_substring += 2;
+		  }
+		*current_substring++ = *(percent_loc + 2);
+		this_argclass = long_long_arg;
+	      }
+	  }
+#endif	/* defined __MINGW32__ && !defined __USE_MINGW_ANSI_STDIO */
 	else
 	  {
 	    strncpy (current_substring, percent_loc, f - percent_loc);



More information about the Gdb-patches mailing list