public inbox for elfutils@sourceware.org
 help / color / mirror / Atom feed
From: "Frank Ch. Eigler" <fche@redhat.com>
To: elfutils-devel@sourceware.org
Cc: amerey@redhat.com
Subject: patch 3/3 debuginfod client interruptability
Date: Mon, 04 Nov 2019 21:48:00 -0000	[thread overview]
Message-ID: <20191104214823.GA17633@redhat.com> (raw)
In-Reply-To: <20191028190726.GE14349@redhat.com>

Hi -

At the wise counsel of gdb folks such as <tromey> and <simark>:

    debuginfod 3/3: client interruptability
    
    For interactive clients such as gdb, interruptibility is important for
    usability during longer downloads.  This patchset adds a
    download-progress callback function to the debuginfod client library,
    with which a caller app can interrupt a download as well as be
    notified of its quantitative progress.

diff --git a/debuginfod/ChangeLog b/debuginfod/ChangeLog
index b5679a2f9d16..34713746350d 100644
--- a/debuginfod/ChangeLog
+++ b/debuginfod/ChangeLog
@@ -1,3 +1,18 @@
+2019-11-04  Frank Ch. Eigler  <fche@redhat.com>
+
+	* debuginfo-client.c (debuginfod_set_progressfn): New function
+	for progress/interrupt callback.
+	(debuginfod_clean_cache, debuginfod_query_server): Call it.
+	* debuginfo.h: Declare it.
+	* debuginfod_set_progressfn.3, *_find_debuginfo.3: Document it.
+	* Makefile.am: Install it.
+	* libdebuginfod.map: Export it all under ELFUTILS_0.178 symversion.
+
+	* debuginfod-find.c: Add -v option to activate progress cb.
+	* debuginfod-find.1: Document it.
+	* debuginfod.cxx: Add $DEBUGINFOD_TEST_WEBAPI_SLEEP env var
+	to insert sleep in webapi callbacks, to help manual testing.
+
 2019-10-28  Frank Ch. Eigler  <fche@redhat.com>
 
 	* debuginfod.cxx: New file: debuginfod server.
diff --git a/debuginfod/Makefile.am b/debuginfod/Makefile.am
index 6e5c7290e68d..790e42317972 100644
--- a/debuginfod/Makefile.am
+++ b/debuginfod/Makefile.am
@@ -60,7 +60,7 @@ debuginfod_SOURCES = debuginfod.cxx
 debuginfod_cxx_CXXFLAGS = -Wno-unused-functions
 # g++ 4.8 on rhel7 otherwise errors gthr-default.h / __gthrw2(__gthrw_(__pthread_key_create) undefs
 dist_man8_MANS = debuginfod.8
-dist_man3_MANS = debuginfod_find_debuginfo.3 debuginfod_find_source.3 debuginfod_find_executable.3
+dist_man3_MANS = debuginfod_find_debuginfo.3 debuginfod_find_source.3 debuginfod_find_executable.3 debuginfod_set_progressfn.3
 dist_man1_MANS = debuginfod-find.1
 debuginfod_LDADD = $(libdw) $(libelf) $(libeu) $(libdebuginfod) $(libmicrohttpd_LIBS) $(libcurl_LIBS) $(sqlite3_LIBS) $(libarchive_LIBS) -lpthread -ldl
 
diff --git a/debuginfod/debuginfod-client.c b/debuginfod/debuginfod-client.c
index dd8d99c7af17..6a1ffbf7455f 100644
--- a/debuginfod/debuginfod-client.c
+++ b/debuginfod/debuginfod-client.c
@@ -28,6 +28,7 @@
 
 #include "config.h"
 #include "debuginfod.h"
+#include "atomics.h"
 #include <assert.h>
 #include <dirent.h>
 #include <stdio.h>
@@ -77,6 +78,9 @@ static const char url_delim_char = ' ';
 static const char *server_timeout_envvar = DEBUGINFOD_TIMEOUT_ENV_VAR;
 static int server_timeout = 5;
 
+/* Progress/interrupt callback function. */
+static debuginfod_progressfn_t progressfn;
+
 /* Data associated with a particular CURL easy handle. Passed to
    the write callback.  */
 struct handle_data
@@ -207,8 +211,14 @@ debuginfod_clean_cache(char *cache_path, char *interval_path, char *max_unused_p
     return -errno;
 
   FTSENT *f;
+  long files = 0;
   while ((f = fts_read(fts)) != NULL)
     {
+      files++;
+      if (progressfn) /* inform/check progress callback */
+        if ((*progressfn) (files, 0))
+          break;
+
       switch (f->fts_info)
         {
         case FTS_F:
@@ -237,7 +247,8 @@ debuginfod_clean_cache(char *cache_path, char *interval_path, char *max_unused_p
 /* Query each of the server URLs found in $DEBUGINFOD_URLS for the file
    with the specified build-id, type (debuginfo, executable or source)
    and filename. filename may be NULL. If found, return a file
-   descriptor for the target, otherwise return an error code.  */
+   descriptor for the target, otherwise return an error code.
+*/
 static int
 debuginfod_query_server (const unsigned char *build_id,
                          int build_id_len,
@@ -446,10 +457,35 @@ debuginfod_query_server (const unsigned char *build_id,
 
   /* Query servers in parallel.  */
   int still_running;
+  unsigned loops = 0;
   do
     {
       CURLMcode curl_res;
 
+      if (progressfn) /* inform/check progress callback */
+        {
+          loops ++;
+          long pa = loops; /* default params for progress callback */
+          long pb = 0;
+          if (target_handle) /* we've committed to a server; report its download progress */
+            {
+              curl_off_t cl, dl;
+              curl_res = curl_easy_getinfo(target_handle,
+                                           CURLINFO_SIZE_DOWNLOAD_T,
+                                           &dl);
+              if (curl_res == 0 && dl >= 0)
+                pa = (dl > LONG_MAX ? LONG_MAX : (long)dl);
+
+              curl_res = curl_easy_getinfo(target_handle,
+                                           CURLINFO_CONTENT_LENGTH_DOWNLOAD_T,
+                                           &cl);
+              if (curl_res == 0 && cl >= 0)
+                pb = (cl > LONG_MAX ? LONG_MAX : (long)cl);
+            }
+          if ((*progressfn) (pa, pb))
+            break;
+        }
+
       /* Wait 1 second, the minimum DEBUGINFOD_TIMEOUT.  */
       curl_multi_wait(curlm, NULL, 0, 1000, NULL);
 
@@ -600,16 +636,21 @@ debuginfod_find_executable(const unsigned char *build_id, int build_id_len,
 }
 
 /* See debuginfod.h  */
-int debuginfod_find_source(const unsigned char *build_id,
-                          int build_id_len,
-                          const char *filename,
-                          char **path)
+int debuginfod_find_source(const unsigned char *build_id, int build_id_len,
+                           const char *filename, char **path)
 {
   return debuginfod_query_server(build_id, build_id_len,
                                  "source", filename, path);
 }
 
 
+debuginfod_progressfn_t
+debuginfod_set_progressfn(debuginfod_progressfn_t fn)
+{
+  debuginfod_progressfn_t it = atomic_exchange (& progressfn, fn);
+  return it;
+}
+
 
 /* NB: these are thread-unsafe. */
 __attribute__((constructor)) attribute_hidden void libdebuginfod_ctor(void)
diff --git a/debuginfod/debuginfod-find.1 b/debuginfod/debuginfod-find.1
index 6d2251662a57..4c352a4f2873 100644
--- a/debuginfod/debuginfod-find.1
+++ b/debuginfod/debuginfod-find.1
@@ -18,11 +18,11 @@
 debuginfod-find \- request debuginfo-related data
 
 .SH SYNOPSIS
-.B debuginfod-find debuginfo \fIBUILDID\fP
+.B debuginfod-find [\fIOPTION\fP]... debuginfo \fIBUILDID\fP
 
-.B debuginfod-find executable \fIBUILDID\fP
+.B debuginfod-find [\fIOPTION\fP]... executable \fIBUILDID\fP
 
-.B debuginfod-find source \fIBUILDID\fP \fI/FILENAME\fP
+.B debuginfod-find [\fIOPTION\fP]... source \fIBUILDID\fP \fI/FILENAME\fP
 
 .SH DESCRIPTION
 \fBdebuginfod-find\fP queries one or more \fBdebuginfod\fP servers for
@@ -91,6 +91,13 @@ l l.
 \../bar/foo.c AT_comp_dir=/zoo	source BUILDID /zoo/../bar/foo.c
 .TE
 
+.SH "OPTIONS"
+
+.TP
+.B "\-v"
+Increase verbosity, including printing frequent download-progress messages.
+
+
 .SH "SECURITY"
 
 debuginfod-find \fBdoes not\fP include any particular security
diff --git a/debuginfod/debuginfod-find.c b/debuginfod/debuginfod-find.c
index 78322fc6cd29..e26919ae7c53 100644
--- a/debuginfod/debuginfod-find.c
+++ b/debuginfod/debuginfod-find.c
@@ -51,10 +51,39 @@ static const char args_doc[] = N_("debuginfo BUILDID\n"
                                   "executable BUILDID\n"
                                   "source BUILDID /FILENAME");
 
+/* Definitions of arguments for argp functions.  */
+static const struct argp_option options[] =
+  {
+   { "verbose", 'v', NULL, 0, "Increase verbosity.", 0 },
+   { NULL, 0, NULL, 0, NULL, 0 }
+  };
+
+
+
+int progressfn(long a, long b)
+{
+  fprintf (stderr, "Progress %ld / %ld\n", a, b);
+  return 0;
+}
+
+
+static error_t parse_opt (int key, char *arg, struct argp_state *state)
+{
+  (void) arg;
+  (void) state;
+  switch (key)
+    {
+    case 'v': debuginfod_set_progressfn (& progressfn); break;
+    default: return ARGP_ERR_UNKNOWN;
+    }
+  return 0;
+}
+
+
 /* Data structure to communicate with argp functions.  */
 static struct argp argp =
   {
-   NULL, NULL, args_doc, doc, NULL, NULL, NULL
+   options, parse_opt, args_doc, doc, NULL, NULL, NULL
   };
 
 
diff --git a/debuginfod/debuginfod.cxx b/debuginfod/debuginfod.cxx
index c9d5b271b328..fe8706cf3e07 100644
--- a/debuginfod/debuginfod.cxx
+++ b/debuginfod/debuginfod.cxx
@@ -370,6 +370,8 @@ static set<string> source_paths;
 static vector<string> extra_ddl;
 static regex_t file_include_regex;
 static regex_t file_exclude_regex;
+static int test_webapi_sleep; /* testing only */
+
 
 /* Handle program arguments.  */
 static error_t
@@ -922,6 +924,15 @@ handle_buildid_match (int64_t b_mtime,
 }
 
 
+static int
+debuginfod_find_progress (long a, long b)
+{
+  if (verbose > 4)
+    obatched(clog) << "federated debuginfod progress=" << a << "/" << b << endl;
+
+  return interrupted;
+}
+
 
 static struct MHD_Response* handle_buildid (const string& buildid /* unsafe */,
                                             const string& artifacttype /* unsafe */,
@@ -1004,6 +1015,7 @@ static struct MHD_Response* handle_buildid (const string& buildid /* unsafe */,
 
   // We couldn't find it in the database.  Last ditch effort
   // is to defer to other debuginfo servers.
+
   int fd = -1;
   if (artifacttype == "debuginfo")
     fd = debuginfod_find_debuginfo ((const unsigned char*) buildid.c_str(), 0,
@@ -1070,6 +1082,9 @@ handler_cb (void * /*cls*/,
   if (verbose)
     obatched(clog) << conninfo(connection) << " " << method << " " << url << endl;
 
+  if (test_webapi_sleep)
+    sleep (test_webapi_sleep);
+
   try
     {
       if (string(method) != "GET")
@@ -2303,6 +2318,10 @@ main (int argc, char *argv[])
   if (rc != 0)
     error (EXIT_FAILURE, 0, "regcomp failure: %d", rc);
 
+  const char* test_webapi_sleep_str = getenv("DEBUGINFOD_TEST_WEBAPI_SLEEP");
+  if (test_webapi_sleep_str)
+    test_webapi_sleep = atoi (test_webapi_sleep_str);
+
   /* Parse and process arguments.  */
   int remaining;
   argp_program_version_hook = print_version; // this works
@@ -2357,6 +2376,8 @@ main (int argc, char *argv[])
              "cannot run database schema ddl: %s", sqlite3_errmsg(db));
     }
 
+  (void) debuginfod_set_progressfn (& debuginfod_find_progress);
+
   // Start httpd server threads.  Separate pool for IPv4 and IPv6, in
   // case the host only has one protocol stack.
   MHD_Daemon *d4 = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
diff --git a/debuginfod/debuginfod.h b/debuginfod/debuginfod.h
index c268ffebcdb6..2e597013ffbf 100644
--- a/debuginfod/debuginfod.h
+++ b/debuginfod/debuginfod.h
@@ -61,6 +61,9 @@ int debuginfod_find_source (const unsigned char *build_id,
                             const char *filename,
                             char **path);
 
+typedef int (*debuginfod_progressfn_t)(long a, long b);
+debuginfod_progressfn_t debuginfod_set_progressfn(debuginfod_progressfn_t fn);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/debuginfod/debuginfod_find_debuginfo.3 b/debuginfod/debuginfod_find_debuginfo.3
index 18caec5576ba..7cd30810e252 100644
--- a/debuginfod/debuginfod_find_debuginfo.3
+++ b/debuginfod/debuginfod_find_debuginfo.3
@@ -13,7 +13,7 @@
 .RE
 ..
 
-.TH DEBUGINFOD_FIND_DEBUGINFO 3
+.TH DEBUGINFOD_FIND_* 3
 .SH NAME
 debuginfod_find_debuginfo \- request debuginfo from debuginfod
 
@@ -21,9 +21,13 @@ debuginfod_find_debuginfo \- request debuginfo from debuginfod
 .nf
 .B #include <elfutils/debuginfod.h>
 .PP
-.BI "debuginfod_find_debuginfo(const unsigned char *" build_id ", int " build_id_len ", char ** " path ");"
-.BI "debuginfod_find_executable(const unsigned char *" build_id ", int " build_id_len ", char ** " path ");"
-.BI "debuginfod_find_source(const unsigned char *" build_id ", int " build_id_len ", const char *" filename ", char ** " path ");"
+.BI "int debuginfod_find_debuginfo(const unsigned char *" build_id ", int " build_id_len ", char ** " path ");"
+.BI "int debuginfod_find_executable(const unsigned char *" build_id ", int " build_id_len ", char ** " path ");"
+.BI "int debuginfod_find_source(const unsigned char *" build_id ", int " build_id_len ", const char *" filename ", char ** " path ");"
+.BI "typedef int (*debuginfo_progressfn_t)(long a, long b);"
+.BI "debuginfo_progressfn_t debuginfod_set_progressfn(debuginfo_progressfn_t " progressfn ");"
+
+Link with \fB-ldebuginfod\fP.
 
 .SH DESCRIPTION
 .BR debuginfod_find_debuginfo (),
@@ -56,6 +60,35 @@ The URLs in \fB$DEBUGINFOD_URLS\fP are queried in parallel. As soon as a
 debuginfod server begins transfering the target file all of the connections
 to the other servers are closed.
 
+.SH "RETURN VALUE"
+If a find family function is successful, the resulting file is saved
+to the client cache and a file descriptor to that file is returned.
+The caller needs to \fBclose\fP() this descriptor.  Otherwise, a
+negative error code is returned.
+
+.SH "PROGRESS CALLBACK"
+
+As the \fBdebuginfod_find_*\fP() functions may block for seconds or longer, a progress
+callback function is called periodically, if configured with
+.BR debuginfod_set_progressfn ().
+This function sets a new progress callback function (or NULL) and
+returns the previously set function (or NULL).
+
+The given callback function is called from the context of each thread
+that is invoking any of the other lookup functions.  It is given two
+numeric parameters that, if thought of as a numerator \fIa\fP and
+denominator \fIb\fP, together represent a completion fraction
+\fIa/b\fP.  The denominator may be zero initially, until a quantity
+such as an exact download size becomes known.
+
+The progress callback function is also the supported way to
+\fIinterrupt\fP the download operation.  (The library does \fInot\fP
+modify or trigger signals.)  The progress callback must return 0 to
+continue the work, or any other value to stop work as soon as
+possible.  Consequently, the \fBdebuginfod_find_*\fP() function will
+likely return with an error, but might still succeed.
+
+
 .SH "CACHE"
 If the query is successful, the \fBdebuginfod_find_*\fP() functions save
 the target file to a local cache. The location of the cache is controlled
@@ -99,11 +132,6 @@ This environment variable governs the location of the cache where
 downloaded files are kept.  It is cleaned periodically as this
 program is reexecuted.  The default is $HOME/.debuginfod_client_cache.
 
-.SH "RETURN VALUE"
-If the query is successful, these functions save the target file
-to the client cache and return a file descriptor to that file.
-Otherwise an error code is returned.
-
 .SH "ERRORS"
 The following list is not comprehensive. Error codes may also
 originate from calls to various C Library functions.
diff --git a/debuginfod/debuginfod_set_progressfn.3 b/debuginfod/debuginfod_set_progressfn.3
new file mode 100644
index 000000000000..16279936e2ea
--- /dev/null
+++ b/debuginfod/debuginfod_set_progressfn.3
@@ -0,0 +1 @@
+.so man3/debuginfod_find_debuginfo.3
diff --git a/debuginfod/libdebuginfod.map b/debuginfod/libdebuginfod.map
index 50d6fbaec639..b322cba644f5 100644
--- a/debuginfod/libdebuginfod.map
+++ b/debuginfod/libdebuginfod.map
@@ -1,7 +1,8 @@
 ELFUTILS_0 { };
-ELFUTILS_0.177 {
+ELFUTILS_0.178 {
   global:
   debuginfod_find_debuginfo;
   debuginfod_find_executable;
   debuginfod_find_source;
+  debuginfod_set_progressfn;
 } ELFUTILS_0;
diff --git a/tests/ChangeLog b/tests/ChangeLog
index ef5f2f0f1211..7b091158cff2 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,7 @@
+2019-11-04  Frank Ch. Eigler  <fche@redhat.com>
+
+	* run-debuginfod-find.sh: Test debuginfod-find -v progress mode.
+
 2019-10-28  Aaron Merey  <amerey@redhat.com>
 	    Frank Ch. Eigler  <fche@redhat.com>
 
diff --git a/tests/run-debuginfod-find.sh b/tests/run-debuginfod-find.sh
index 2facef2cbaad..fe38eaac9c77 100755
--- a/tests/run-debuginfod-find.sh
+++ b/tests/run-debuginfod-find.sh
@@ -44,7 +44,7 @@ ldpath=`testrun sh -c 'echo $LD_LIBRARY_PATH'`
 
 mkdir F R
 tempfiles F R
-env LD_LIBRARY_PATH=$ldpath DEBUGINFOD_URLS= ${abs_builddir}/../debuginfod/debuginfod -vvvv -d $DB \
+env DEBUGINFOD_TEST_WEBAPI_SLEEP=3 LD_LIBRARY_PATH=$ldpath DEBUGINFOD_URLS= ${abs_builddir}/../debuginfod/debuginfod -vvvv -d $DB \
 -p $PORT1 -t0 -g0 R F &
 PID1=$!
 sleep 3
@@ -105,8 +105,11 @@ kill -USR1 $PID1
 sleep 3
 
 # Rerun same tests for the prog2 binary
-filename=`testrun ${abs_top_builddir}/debuginfod/debuginfod-find debuginfo $BUILDID2`
+filename=`testrun ${abs_top_builddir}/debuginfod/debuginfod-find -v debuginfo $BUILDID2 2>vlog`
 cmp $filename F/prog2
+cat vlog
+grep -q Progress vlog
+tempfiles vlog
 filename=`testrun ${abs_top_builddir}/debuginfod/debuginfod-find executable $BUILDID2`
 cmp $filename F/prog2
 filename=`testrun ${abs_top_builddir}/debuginfod/debuginfod-find source $BUILDID2 ${PWD}/prog2.c`

  reply	other threads:[~2019-11-04 21:48 UTC|newest]

Thread overview: 78+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-10-28 19:04 patch 0/2 debuginfod submission Frank Ch. Eigler
2019-10-28 19:06 ` patch 1/2 debuginfod client Frank Ch. Eigler
2019-10-28 19:09   ` patch 2/2 debuginfod server etc Frank Ch. Eigler
2019-11-04 21:48     ` Frank Ch. Eigler [this message]
2019-11-07  9:07       ` patch 4 debuginfod: symlink following mode Frank Ch. Eigler
2019-11-07  9:08         ` patch 5 debuginfod: prometheus metrics Frank Ch. Eigler
2019-11-15 17:26           ` Mark Wielaard
2019-11-15 17:58             ` Frank Ch. Eigler
2019-11-18 16:20               ` Mark Wielaard
2019-11-18 16:48                 ` Frank Ch. Eigler
2019-11-19 16:13                   ` Mark Wielaard
2019-11-15 16:49         ` patch 4 debuginfod: symlink following mode Mark Wielaard
2019-11-15 18:31           ` Frank Ch. Eigler
2019-11-18 16:27             ` Mark Wielaard
2019-11-15 16:16       ` patch 3/3 debuginfod client interruptability Mark Wielaard
2019-11-15 17:03         ` Aaron Merey
2019-11-15 17:35           ` Mark Wielaard
2019-11-15 18:14             ` Pedro Alves
2019-11-17 23:44               ` Mark Wielaard
2019-11-18  2:50                 ` Frank Ch. Eigler
2019-11-18  9:24                   ` Pedro Alves
2019-11-19 12:58                   ` Mark Wielaard
2019-11-13 17:22     ` patch 2/2 debuginfod server etc Mark Wielaard
2019-11-14 11:54       ` Frank Ch. Eigler
2019-11-16  1:31         ` Mark Wielaard
2019-11-13 23:19     ` Mark Wielaard
2019-11-14 12:30       ` Frank Ch. Eigler
2019-11-18 14:17         ` Mark Wielaard
2019-11-18 18:41           ` Frank Ch. Eigler
2019-11-19 15:41             ` Mark Wielaard
2019-11-19 16:13               ` Frank Ch. Eigler
2019-11-19 20:11                 ` Mark Wielaard
2019-11-19 21:15                   ` Frank Ch. Eigler
2019-11-20 11:53                     ` Mark Wielaard
2019-11-20 12:29                       ` Frank Ch. Eigler
2019-11-21 14:16                       ` Mark Wielaard
2019-11-21 15:40                         ` Mark Wielaard
2019-11-21 16:01                           ` Frank Ch. Eigler
2019-11-21 15:58                         ` Frank Ch. Eigler
2019-11-21 16:37                           ` Mark Wielaard
2019-11-21 17:18                             ` Frank Ch. Eigler
2019-11-21 20:42                               ` Mark Wielaard
2019-11-22 12:08                                 ` Mark Wielaard
2019-11-14 20:45     ` Mark Wielaard
2019-11-15 11:03       ` Mark Wielaard
2019-11-15 21:00       ` Frank Ch. Eigler
2019-11-18 15:01         ` Mark Wielaard
2019-11-15 14:40     ` Mark Wielaard
2019-11-15 19:54       ` Frank Ch. Eigler
2019-11-18 15:31         ` Mark Wielaard
2019-11-18 15:49           ` Frank Ch. Eigler
2019-11-12 11:12   ` patch 1/2 debuginfod client Mark Wielaard
2019-11-12 15:14     ` Frank Ch. Eigler
2019-11-12 21:59       ` Mark Wielaard
2019-11-14  0:33         ` Frank Ch. Eigler
2019-11-15 21:33       ` Mark Wielaard
2019-11-12 21:25   ` Mark Wielaard
2019-11-13 23:25     ` Frank Ch. Eigler
2019-11-16  0:46       ` Mark Wielaard
2019-11-16 18:53         ` Frank Ch. Eigler
2019-11-18 17:17           ` Mark Wielaard
2019-11-18 20:33             ` Frank Ch. Eigler
2019-11-19 15:57               ` Mark Wielaard
2019-11-19 16:20                 ` Frank Ch. Eigler
2019-11-19 20:16                   ` Mark Wielaard
2019-11-19 21:22                     ` Frank Ch. Eigler
2019-11-20 12:50                       ` Mark Wielaard
2019-11-20 13:30                         ` Frank Ch. Eigler
2019-11-21 14:02                           ` Mark Wielaard
2019-11-13 13:57   ` Mark Wielaard
2019-11-14 11:24     ` Frank Ch. Eigler
2019-11-16  0:52       ` Mark Wielaard
2019-11-16  2:28         ` Frank Ch. Eigler
2019-10-30 11:04 ` patch 0/2 debuginfod submission Mark Wielaard
2019-10-30 13:40   ` Frank Ch. Eigler
2019-10-30 14:12     ` Mark Wielaard
2019-10-30 18:11       ` Frank Ch. Eigler
2019-10-31 11:18         ` Mark Wielaard

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=20191104214823.GA17633@redhat.com \
    --to=fche@redhat.com \
    --cc=amerey@redhat.com \
    --cc=elfutils-devel@sourceware.org \
    /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;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).