Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Matthieu Longo <matthieu.longo@arm.com>
To: <gdb-patches@sourceware.org>
Cc: Andrew Burgess <aburgess@redhat.com>, Tom Tromey <tom@tromey.com>,
	Matthieu Longo <matthieu.longo@arm.com>,
	Thiago Jung Bauermann <thiago.bauermann@linaro.org>
Subject: [PATCH v3 7/8] gdb/linux-tdep: use target_file_reader for procfs parsing
Date: Tue, 22 Sep 2026 14:50:49 +0100	[thread overview]
Message-ID: <20260922135050.236941-8-matthieu.longo@arm.com> (raw)
In-Reply-To: <20260922135050.236941-1-matthieu.longo@arm.com>

Migrate procfs reads in linux_info_proc and linux_find_memory_regions_full
from the target_fileio_* allocation helpers to target_file_reader.

Use the array views provided by target_file_reader to simplify the parsing
of procfs contents. In particular, use gdb::ranges::replace for the
NUL-separated command line and extract_view_from_buffer for environment
entries.

Reviewed-By: Thiago Jung Bauermann <thiago.bauermann@linaro.org>
---
 gdb/linux-tdep.c | 120 ++++++++++++++++++++++-------------------------
 1 file changed, 57 insertions(+), 63 deletions(-)

diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c
index 0582e5eee64..bb1870efe08 100644
--- a/gdb/linux-tdep.c
+++ b/gdb/linux-tdep.c
@@ -45,6 +45,7 @@
 #include "memtag.h"
 #include "cli/cli-style.h"
 #include "gdbsupport/unordered_map.h"
+#include "gdbsupport/ranges.h"
 
 #include <algorithm>
 
@@ -939,26 +940,26 @@ linux_info_proc (struct gdbarch *gdbarch, const char *args,
 
   if (cmdline_f)
     {
-      xsnprintf (filename, sizeof filename, "/proc/%ld/cmdline", ptid.lwp ());
-      gdb_byte *buffer;
-      LONGEST len = target_fileio_read_alloc (nullptr, filename, &buffer);
-
-      if (len > 0)
+      std::string path = string_printf ("/proc/%ld/cmdline", ptid.lwp ());
+      target_file_reader<gdb_byte> cmdline_freader (path);
+      if (!cmdline_freader.empty_or_error ())
 	{
-	  gdb::unique_xmalloc_ptr<char> cmdline ((char *) buffer);
-	  ssize_t pos;
-
-	  for (pos = 0; pos < len - 1; pos++)
-	    {
-	      if (buffer[pos] == '\0')
-		buffer[pos] = ' ';
-	    }
-	  buffer[len - 1] = '\0';
-	  gdb_printf ("cmdline = '%s'\n", buffer);
+	  /* /proc/<pid>/cmdline stores the command-line arguments as a
+	     sequence of NUL-separated strings.  */
+	  gdb::array_view<char> cmdline = cmdline_freader.cast_view<char> ();
+	  if (cmdline[cmdline.size () - 1] != '\0')
+	    warning (_("malformed '%ps', missing null-terminating character"),
+		     styled_string (file_name_style.style (), path.c_str ()));
+	  /* Replace null characters splitting the arguments in the command
+	     line by spaces, except for the last one.  */
+	  gdb::ranges::replace
+	    (cmdline.slice (0, cmdline.size () - 1), '\0', ' ');
+	  gdb_printf ("cmdline = '%s'\n", cmdline.data ());
 	}
       else
 	warning (_("unable to open /proc file '%ps'"),
-		 styled_string (file_name_style.style (), filename));
+		 styled_string (file_name_style.style (),
+				cmdline_freader.c_path ()));
     }
   if (cwd_f)
     {
@@ -973,28 +974,26 @@ linux_info_proc (struct gdbarch *gdbarch, const char *args,
     }
   if (environ_f)
     {
-      xsnprintf (filename, sizeof filename, "/proc/%ld/environ", ptid.lwp ());
-      gdb_byte *buffer;
-      LONGEST len = target_fileio_read_alloc (nullptr, filename, &buffer);
-
-      if (len > 0)
+      target_file_reader<gdb_byte> environ_freader
+	(string_printf ("/proc/%ld/environ", ptid.lwp ()));
+      if (!environ_freader.empty_or_error ())
 	{
-	  gdb::unique_xmalloc_ptr<char> dealloc ((char *) buffer);
 	  gdb_printf (_("Environment variables:\n\n"));
-
+	  gdb::array_view<char> buffer = environ_freader.cast_view<char> ();
 	  /* Entries are separated by the null character.
 	     Print each environment variable, line by line.  */
-	  gdb_byte *buffer_end = buffer + len;
-	  while (buffer < buffer_end)
+	  for (auto it = buffer.begin (); it != buffer.end ();)
 	    {
-	      gdb_printf ("  %s\n", buffer);
-	      /* +1 for the null character.  */
-	      buffer += strlen ((char *) buffer) + 1;
+	      auto [ntbs, next_start]
+		= extract_next_field (buffer, it, '\0');
+	      gdb_printf ("  %s\n", ntbs.data ());
+	      it = next_start;
 	    }
 	}
       else
 	warning (_("unable to open /proc file '%ps'"),
-		 styled_string (file_name_style.style (), filename));
+		 styled_string (file_name_style.style (),
+				environ_freader.c_path ()));
     }
   if (exe_f)
     {
@@ -1009,11 +1008,9 @@ linux_info_proc (struct gdbarch *gdbarch, const char *args,
     }
   if (mappings_f)
     {
-      xsnprintf (filename, sizeof filename, "/proc/%ld/maps", ptid.lwp ());
-      LONGEST len = 0;
-      gdb::unique_xmalloc_ptr<char> map
-	= target_fileio_read_stralloc (NULL, filename, &len);
-      if (map != NULL)
+      target_file_reader<char> map_freader
+	(string_printf ("/proc/%ld/maps", ptid.lwp ()));
+      if (!map_freader.empty_or_error ())
 	{
 	  gdb_printf (_("Mapped address spaces:\n\n"));
 	  ui_out_emit_table emitter (current_uiout, 6, -1, "ProcMappings");
@@ -1027,12 +1024,13 @@ linux_info_proc (struct gdbarch *gdbarch, const char *args,
 	  current_uiout->table_header (0, ui_left, "objfile", "File");
 	  current_uiout->table_body ();
 
-	  gdb::array_view<char> content (map.get (), len);
+	  auto content = map_freader.view ();
 	  for (auto it = content.begin (); it != content.end ();)
 	    {
 	      auto [line, next_line_begin]
 		= extract_next_field (content, it, '\n');
 	      it = next_line_begin;
+
 	      mapping m = read_mapping (line);
 
 	      ui_out_emit_tuple tuple_emitter (current_uiout);
@@ -1053,27 +1051,27 @@ linux_info_proc (struct gdbarch *gdbarch, const char *args,
 	}
       else
 	warning (_("unable to open /proc file '%ps'"),
-		 styled_string (file_name_style.style (), filename));
+		 styled_string (file_name_style.style (),
+				map_freader.c_path ()));
     }
   if (status_f)
     {
-      xsnprintf (filename, sizeof filename, "/proc/%ld/status", ptid.lwp ());
-      gdb::unique_xmalloc_ptr<char> status
-	= target_fileio_read_stralloc (NULL, filename);
-      if (status)
-	gdb_puts (status.get ());
+      target_file_reader<char> status_freader
+	(string_printf ("/proc/%ld/status", ptid.lwp ()));
+      if (!status_freader.empty_or_error ())
+	gdb_puts (status_freader.data ());
       else
 	warning (_("unable to open /proc file '%ps'"),
-		 styled_string (file_name_style.style (), filename));
+		 styled_string (file_name_style.style (),
+				status_freader.c_path ()));
     }
   if (stat_f)
     {
-      xsnprintf (filename, sizeof filename, "/proc/%ld/stat", ptid.lwp ());
-      gdb::unique_xmalloc_ptr<char> statstr
-	= target_fileio_read_stralloc (NULL, filename);
-      if (statstr)
+      target_file_reader<char> stat_freader
+	(string_printf ("/proc/%ld/stat", ptid.lwp ()));
+      if (!stat_freader.empty_or_error ())
 	{
-	  const char *p = statstr.get ();
+	  const char *p = stat_freader.data ();
 
 	  gdb_printf (_("Process: %s\n"),
 		      pulongest (strtoulst (p, &p, 10)));
@@ -1201,7 +1199,8 @@ linux_info_proc (struct gdbarch *gdbarch, const char *args,
 	}
       else
 	warning (_("unable to open /proc file '%ps'"),
-		 styled_string (file_name_style.style (), filename));
+		 styled_string (file_name_style.style (),
+				stat_freader.c_path ()));
     }
 }
 
@@ -1835,27 +1834,22 @@ linux_find_memory_regions_full (struct gdbarch *gdbarch,
 	}
     }
 
-  std::string maps_filename = string_printf ("/proc/%ld/smaps", ptid.lwp ());
-
-  LONGEST len = 0;
-  gdb::unique_xmalloc_ptr<char> data
-    = target_fileio_read_stralloc (NULL, maps_filename.c_str (), &len);
+  std::vector<smaps_data> smaps;
 
-  if (data == NULL)
+  target_file_reader<char> smaps_freader
+    (string_printf ("/proc/%ld/smaps", ptid.lwp ()));
+  if (!smaps_freader.empty_or_error ())
+    smaps = parse_smaps_data (smaps_freader);
+  else
     {
       /* Older Linux kernels did not support /proc/PID/smaps.  */
-      maps_filename = string_printf ("/proc/%ld/maps", ptid.lwp ());
-      data = target_fileio_read_stralloc (NULL, maps_filename.c_str (), &len);
-
-      if (data == nullptr)
+      target_file_reader<char> maps_freader
+	(string_printf ("/proc/%ld/maps", ptid.lwp ()));
+      if (maps_freader.empty_or_error ())
 	return false;
+      smaps = parse_smaps_data (maps_freader);
     }
 
-  /* Parse the contents of smaps into a vector.  */
-  gdb::array_view<char> content (data.get (), len);
-  std::vector<smaps_data> smaps
-    = parse_smaps_data (content, maps_filename);
-
   for (const smaps_data &map: smaps)
     {
       /* Invoke the callback function to create the corefile segment.  */
-- 
2.55.0


  parent reply	other threads:[~2026-09-22 13:53 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-22 13:50 [PATCH v3 0/8] gdb: introduce file_reader_t to read procfs files Matthieu Longo
2026-09-22 13:50 ` [PATCH v3 1/8] gdb support: add gdb::ranges::replace algorithm Matthieu Longo
2026-09-22 13:50 ` [PATCH v3 2/8] gdb/linux: remove redundant struct prefixes from smaps_data Matthieu Longo
2026-09-22 13:50 ` [PATCH v3 3/8] gdb/linux: style filenames in /proc warning messages Matthieu Longo
2026-09-22 13:50 ` [PATCH v3 4/8] gdbsupport: add extract_next_field helper Matthieu Longo
2026-09-22 13:50 ` [PATCH v3 5/8] gdb/linux: refactor /proc mapping parsing to use array_view Matthieu Longo
2026-09-22 13:50 ` [PATCH v3 6/8] gdb: introduce helper class target_file_reader Matthieu Longo
2026-09-22 13:50 ` Matthieu Longo [this message]
2026-09-22 13:50 ` [PATCH v3 8/8] gdb/linux-tdep: remove legacy parse_smaps_data overload Matthieu Longo

Reply instructions:

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

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

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260922135050.236941-8-matthieu.longo@arm.com \
    --to=matthieu.longo@arm.com \
    --cc=aburgess@redhat.com \
    --cc=gdb-patches@sourceware.org \
    --cc=thiago.bauermann@linaro.org \
    --cc=tom@tromey.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox