[Tarantool-patches] [PATCH luajit 1/2] symtab: fix static symtab dump

Maxim Kokryashkin max.kokryashkin at gmail.com
Mon Jul 4 00:38:14 MSK 2022


The `dl_iterate_phdr` returns an empty string as a name for
the executable from which it was called. It is still possible
to access its dynamic symbol table, but it is vital for
sysprof to obtain the main symbol table for the LuaJIT
executable. To do so, we need a valid path to the executable.

Since there is no way to obtain the path to a running executable
using the C standard library, this commit adds call to
`readlink` to gather the symbolic link from `/proc/self/exe`.
Most of the UNIX-based systems have procfs, so it is not
a problem.

Needed for tarantool/tarantool#7244
---
 src/lj_symtab.c | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/src/lj_symtab.c b/src/lj_symtab.c
index 2b2b205b..23696401 100644
--- a/src/lj_symtab.c
+++ b/src/lj_symtab.c
@@ -16,10 +16,12 @@
 
 #if LJ_HASRESOLVER
 
+#include <linux/limits.h>
 #include <elf.h>
 #include <link.h>
 #include <stdio.h>
 #include <sys/auxv.h>
+#include <unistd.h>
 #include "lj_gc.h"
 #endif
 
@@ -352,6 +354,7 @@ static int resolve_symbolnames(struct dl_phdr_info *info, size_t info_size,
   struct lj_wbuf *buf = conf->buf;
   lua_State *L = conf->L;
   const uint8_t header = conf->header;
+  char executable_path[PATH_MAX] = "";
 
   uint32_t lib_cnt = 0;
 
@@ -387,6 +390,31 @@ static int resolve_symbolnames(struct dl_phdr_info *info, size_t info_size,
   ** Main way: try to open ELF and read SHT_SYMTAB, SHT_STRTAB and SHT_HASH
   ** sections from it.
   */
+
+  /*
+  ** The `dl_iterate_phdr` returns an empty string as a name for
+  ** the executable from which it was called. It is still possible to
+  ** access its dynamic symbol table, but it is vital for sysprof to obtain
+  ** the main symbol table for the LuaJIT executable. To do so, we need a
+  ** valid path to the executable. Since there is no way to obtain the
+  ** path to a running executable using the C standard library, the only
+  ** more or less reliable way to do this is by reading the symbolic link
+  ** from `/proc/self/exe`. Most of the UNIX-based systems have procfs, so
+  ** it is not a problem.
+  */
+  if (*info->dlpi_name == 0) {
+    if (-1 != readlink("/proc/self/exe", executable_path, PATH_MAX))
+      info->dlpi_name = executable_path;
+    else
+      /*
+      ** It is impossible for sysprof to function properly without the
+      ** LuaJIT's .symtab section present. The assertion below
+      ** is unlikely to be triggered on any system supported by sysprof,
+      ** unless someone have deleted the LuaJIT binary right after the
+      ** start.
+      */
+      lua_assert(0);
+  }
   if (dump_sht_symtab(info->dlpi_name, buf, L, header, info->dlpi_addr) == 0) {
     ++conf->cur_lib;
   }
-- 
2.36.1



More information about the Tarantool-patches mailing list