[sysprof] kallsyms: make SpKallsyms more testable



commit 911d51d44721227225d5e097b2424542ae2cd43e
Author: Christian Hergert <chergert redhat com>
Date:   Mon Jan 29 01:25:14 2018 -0800

    kallsyms: make SpKallsyms more testable
    
    This allows us to pass in the file to read from, and adds a quick test
    case to view the parsed output. It also fixes a base-10 vs base-16
    mistake in parsing addresses.

 daemon/sysprofd.c              |    2 +-
 lib/sp-kallsyms.c              |   20 +++++++++++++-------
 lib/sp-kallsyms.h              |    2 +-
 lib/symbols/sp-kernel-symbol.c |    2 +-
 tests/meson.build              |    5 +++++
 tests/test-kallsyms.c          |   34 ++++++++++++++++++++++++++++++++++
 6 files changed, 55 insertions(+), 10 deletions(-)
---
diff --git a/daemon/sysprofd.c b/daemon/sysprofd.c
index 8544ffe..7536bcc 100644
--- a/daemon/sysprofd.c
+++ b/daemon/sysprofd.c
@@ -76,7 +76,7 @@ sysprofd_get_kernel_symbols (sd_bus_message *msg,
   else if (r == 0)
     return -EACCES;
 
-  if (!(kallsyms = sp_kallsyms_new ()))
+  if (!(kallsyms = sp_kallsyms_new (NULL)))
     {
       sd_bus_error_set (error,
                         SD_BUS_ERROR_FILE_NOT_FOUND,
diff --git a/lib/sp-kallsyms.c b/lib/sp-kallsyms.c
index 3e799cb..daf635f 100644
--- a/lib/sp-kallsyms.c
+++ b/lib/sp-kallsyms.c
@@ -47,13 +47,16 @@ sp_kallsyms_free (SpKallsyms *self)
 }
 
 SpKallsyms *
-sp_kallsyms_new (void)
+sp_kallsyms_new (const gchar *path)
 {
   g_autoptr(SpKallsyms) self = NULL;
 
+  if (path == NULL)
+    path = "/proc/kallsyms";
+
   self = g_slice_new0 (SpKallsyms);
 
-  if (!g_file_get_contents ("/proc/kallsyms", &self->buf, &self->buflen, NULL))
+  if (!g_file_get_contents (path, &self->buf, &self->buflen, NULL))
     return NULL;
 
   self->iter = self->buf;
@@ -70,6 +73,7 @@ sp_kallsyms_next (SpKallsyms   *self,
 {
   guint64 addr;
   char *tok;
+  char *pptr;
 
   g_return_val_if_fail (self != NULL, FALSE);
   g_return_val_if_fail (self->buf != NULL, FALSE);
@@ -93,10 +97,12 @@ try_next:
         return FALSE;
     }
 
-  addr = g_ascii_strtoull (tok, NULL, 10);
-  if ((addr == G_MAXUINT64 && errno == ERANGE) ||
-      (addr == 0 && errno == EINVAL))
-    return FALSE;
+  /* We'll keep going if we fail to parse, (null) usually, so that we
+   * just skip to the next line.
+   */
+  addr = g_ascii_strtoull (tok, &pptr, 16);
+  if ((pptr == tok) || (addr == G_MAXUINT64 && errno == ERANGE) || (addr == 0 && errno == EINVAL))
+    addr = 0;
 
   *address = addr;
 
@@ -139,7 +145,7 @@ try_next:
   if (self->iter >= self->endptr)
     return FALSE;
 
-  if (g_strcmp0 (tok, "(null)") == 0)
+  if (addr == 0)
     goto try_next;
 
   *name = tok;
diff --git a/lib/sp-kallsyms.h b/lib/sp-kallsyms.h
index 76b7a62..0761a42 100644
--- a/lib/sp-kallsyms.h
+++ b/lib/sp-kallsyms.h
@@ -27,7 +27,7 @@ G_BEGIN_DECLS
 
 typedef struct _SpKallsyms SpKallsyms;
 
-SpKallsyms *sp_kallsyms_new  (void);
+SpKallsyms *sp_kallsyms_new  (const gchar  *path);
 gboolean    sp_kallsyms_next (SpKallsyms   *self,
                               const gchar **name,
                               guint64      *address,
diff --git a/lib/symbols/sp-kernel-symbol.c b/lib/symbols/sp-kernel-symbol.c
index 51b3ecf..cc08ac1 100644
--- a/lib/symbols/sp-kernel-symbol.c
+++ b/lib/symbols/sp-kernel-symbol.c
@@ -189,7 +189,7 @@ sp_kernel_symbol_load (void)
   kernel_symbol_strs = g_string_chunk_new (4096);
   ar = g_array_new (FALSE, TRUE, sizeof (SpKernelSymbol));
 
-  if (!(kallsyms = sp_kallsyms_new ()))
+  if (!(kallsyms = sp_kallsyms_new (NULL)))
     goto query_daemon;
 
   while (sp_kallsyms_next (kallsyms, &name, &addr, &type))
diff --git a/tests/meson.build b/tests/meson.build
index 3b87418..1ba0a65 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -18,6 +18,11 @@ test_capture_cursor = executable('test-capture-cursor',
 )
 test('test-capture-cursor', test_capture_cursor, env: test_env)
 
+test_kallsyms = executable('test-kallsyms',
+  ['test-kallsyms.c', '../lib/sp-kallsyms.c'],
+  dependencies: libsysprof_dep,
+)
+
 if get_option('enable_gtk')
 
   test_model_filter = executable('test-model-filter',
diff --git a/tests/test-kallsyms.c b/tests/test-kallsyms.c
new file mode 100644
index 0000000..1395adc
--- /dev/null
+++ b/tests/test-kallsyms.c
@@ -0,0 +1,34 @@
+#include "../lib/sp-address.h"
+#include "../lib/sp-kallsyms.h"
+
+#include <glib.h>
+#include <stdlib.h>
+
+int
+main (gint argc,
+      gchar *argv[])
+{
+  g_autoptr(SpKallsyms) kallsyms = NULL;
+  const gchar *name;
+  SpAddress addr = 0;
+  guint8 type;
+
+  if (argc < 2)
+    {
+      g_printerr ("usage: %s FILE\n", argv[0]);
+      return EXIT_FAILURE;
+    }
+
+  kallsyms = sp_kallsyms_new (argv[1]);
+
+  while (sp_kallsyms_next (kallsyms, &name, &addr, &type))
+    {
+      g_assert (name != NULL);
+      g_assert (addr != 0);
+      g_assert (type != 0);
+
+      g_print ("%s %lx\n", name, addr);
+    }
+
+  return EXIT_SUCCESS;
+}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]