Bug 29997 - search elf symbol table for aliases (fopen -> _IO_new_fopen)
Summary: search elf symbol table for aliases (fopen -> _IO_new_fopen)
Status: RESOLVED FIXED
Alias: None
Product: systemtap
Classification: Unclassified
Component: translator (show other bugs)
Version: unspecified
: P2 normal
Target Milestone: ---
Assignee: Di Chen
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2023-01-13 13:31 UTC by Frank Ch. Eigler
Modified: 2024-01-31 22:39 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Frank Ch. Eigler 2023-01-13 13:31:38 UTC
% stap -L 'process("/lib64/libc.so.6").function("fopen")'

is quiet (no such function in dwarf) but should resolve to the dwarf subprogram _IO_new_fopen
Comment 1 Di Chen 2023-11-03 07:44:33 UTC
[WIP] Two issues might be the culprits.

1) Skipped query_dwarf_func for fopen lacking version info  

In dwflpp::iterate_single_function<void> from dwflpp.cxx, executing
"auto range = v->equal_range(function);" will result in:

  a) fopen cannot be found in unordered_multimap v
  b) fopen64 can be found in v

The following draft diff can prove it, that fopen can be found when version info is added.

```
$ git diff dwflpp.cxx
diff --git a/dwflpp.cxx b/dwflpp.cxx
index a4f66440f..55871635a 100644
--- a/dwflpp.cxx
+++ b/dwflpp.cxx
@@ -1138,6 +1138,11 @@ dwflpp::iterate_single_function<void>(int (*callback)(Dwarf_Die*, void*),
     }
 
   auto range = v->equal_range(function);
+  if (range.first == range.second)
+    {
+    std::string newfunction = function + "@@GLIBC_2.2.5";
+    range = v->equal_range(newfunction);
+    }
   if (range.first != range.second)
     {
       for (auto it = range.first; it != range.second; ++it)

```

2) Module searching failed when using fopen

The module searching happened in dwarf_builder::build, 
when executing "dw->iterate_over_modules<base_query>(&query_module, &q);",
it will call q->handle_query_module() to populate the results.

```
$ gdb --args ../install/bin/stap -L 'process("/lib64/libc.so.6").function("fopen64")'
(gdb) p ((dwarf_query *)q).results
$23 = std::vector of length 0, capacity 0

executing q->handle_query_module();

(gdb) p ((dwarf_query *)q).results
$24 = std::vector of length 1, capacity 1 = {0x1bc5ec00}
```

For fopen, 
$ gdb --args ../install/bin/stap -L 'process("/lib64/libc.so.6").function("fopen")'

"((dwarf_query *)q).results" remains empty after q->handle_query_module().
Comment 2 Di Chen 2023-11-05 04:04:13 UTC
I found the above issue "2) Module searching failed when using fopen" is due to a similar issue like "1)".

It requires a version padding for:

  1) dwflpp::iterate_single_function<void>
  2) dwflpp::iterate_over_functions<void>

I have submitted a PR for this fix and it's ready for review.
https://sourceware.org/pipermail/systemtap/2023q4/027847.html
Comment 3 Di Chen 2023-12-20 03:06:02 UTC
Pushed another PR for wildcard handling.
https://sourceware.org/pipermail/systemtap/2023q4/027922.html

Now it behaves like this:

# no wildcard
$ ../install/bin/stap -L 'process("/lib64/libc.so.6").function("fopen")'
process("/usr/lib64/libc.so.6").function("_IO_new_fopen@/usr/src/debug/glibc-2.37-4.fc38.x86_64/libio/iofopen.c:84") $filename:char const* $mode:char const*

# has wildcard
$ ../install/bin/stap -L 'process("/lib64/libc.so.6").function("fo*en")'
process("/usr/lib64/libc.so.6").function("_IO_new_fopen@/usr/src/debug/glibc-2.37-4.fc38.x86_64/libio/iofopen.c:84") $filename:char const* $mode:char const*
Comment 4 Frank Ch. Eigler 2023-12-20 20:38:18 UTC
OK so the effect of this change is to have the translator prefer symbol-versioned aliases of symbols, in the theory that those versioned names are the ones that people would more likely recognize.  That seems like a good heuristic, go for it.
Comment 5 Aaron Merey 2024-01-31 22:39:58 UTC
Fixed in commit 15d6d16f7d8