]> sourceware.org Git - systemtap.git/commitdiff
Cache the dyninst of the binaries
authorWilliam Cohen <wcohen@redhat.com>
Wed, 13 Oct 2021 14:43:33 +0000 (10:43 -0400)
committerWilliam Cohen <wcohen@redhat.com>
Tue, 26 Oct 2021 13:57:22 +0000 (09:57 -0400)
Reading and processing the binary with dyninst can take a lot of time
(and space).  Added caching to avoid repeated processing of the same
binary.

analysis.cxx
analysis.h
tapsets.cxx

index f2099e3252b8000172299deb07c55b9f6d736c60..d77cf1c3532450118538b1ff04e0fbb8f58c7d07 100644 (file)
@@ -22,27 +22,55 @@ using namespace ParseAPI;
 using namespace std;
 
 
+// Data structures to cache dyninst parsing of binaries
+class bin_info {
+public:
+       bin_info(SymtabCodeSource *s=NULL, CodeObject *c=NULL): sts(s), co(c) {};
+       ~bin_info(){};
+       SymtabCodeSource *sts;
+       CodeObject *co;
+};
+typedef map<string, bin_info> parsed_bin;
+static parsed_bin cached_info;
+
 class analysis {
 public:
-       analysis(char *name);
+       analysis(string name);
        SymtabCodeSource *sts;
        CodeObject *co;
 };
 
 //  Get the binary set up for anaysis
-analysis::analysis(char *name)
+analysis::analysis(string name)
 {
-       // Should see if binary already cached
+       char *name_str = strdup(name.c_str());
        sts = NULL;
        co = NULL;
 
-       // If not seen before
+       // Use cached information if available
+       if (cached_info.find(name) != cached_info.end()) {
+               cout << "liveness analysis using cached info for " << name << endl;
+               sts = cached_info[name].sts;
+               co = cached_info[name].co;
+               goto cleanup;
+       }
+
+       // Not not seen before
        // Create a new binary code object from the filename argument
-       sts = new SymtabCodeSource(name);
-       if(!sts) return;
+       sts = new SymtabCodeSource(name_str);
+       if(!sts) goto cleanup;
 
        co = new CodeObject(sts);
-       if(!co) return;
+       if(!co) goto cleanup;
+
+       // Cache the info for future reference
+       {
+               bin_info entry(sts,co);
+               cached_info.insert(make_pair(name,entry));
+       }
+
+cleanup:
+       free(name_str);
 }
 
 #if defined(__i386__) || defined(__x86_64__)
@@ -187,13 +215,12 @@ static const MachRegister dyninst_register_32[] = {
 };
 #endif
 
-int liveness(const char *executable,
+int liveness(string executable,
             Dwarf_Addr addr,
             location_context ctx)
 {
        // should cache the executable names like the other things
-       char *exe = strdup(executable);
-       analysis func_to_analyze(exe);
+       analysis func_to_analyze(executable);
        MachRegister r;
 
        // Determine whether 32-bit or 64-bit code as the register names are different in dyninst
index 470bca57d26a92bec9ed263dd6bb744aecc40ebe..9b6d115e736a200c661b82a7d45c6911b93ddbe9 100644 (file)
@@ -17,7 +17,7 @@
 
 #ifdef HAVE_DYNINST
 
-extern int liveness(const char *executable,
+extern int liveness(std::string executable,
                    Dwarf_Addr location,
                    location_context ctx);
 
index b8a8c8bc681cbbca14bde631ba9db0e0f7abbaec..5a7ad3ebb919891a05eb452eaa9d4356764c1cd7 100644 (file)
@@ -4732,7 +4732,7 @@ dwarf_var_expanding_visitor::visit_target_symbol (target_symbol *e)
 
       // Now that have location information check if change to variable has any effect
       if (lvalue) {
-             if (liveness(q.dw.mod_info->elf_path.c_str(), addr, ctx) < 0) {
+             if (liveness(q.dw.mod_info->elf_path, addr, ctx) < 0) {
                      q.sess.print_warning(_F("write at %lx will have no effect",
                                              addr), e->tok);
              }
This page took 0.04861 seconds and 5 git commands to generate.