libunwind-devel
[Top][All Lists]
Advanced

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

Re: [Libunwind-devel] negative-caching in dwarf_find_proc_info


From: Milian Wolff
Subject: Re: [Libunwind-devel] negative-caching in dwarf_find_proc_info
Date: Wed, 04 Jun 2014 19:40:15 +0200
User-agent: KMail/4.13.1 (Linux/3.14.4-1-ARCH; KDE/4.13.1; x86_64; ; )

On Wednesday 04 June 2014 19:19:36 Milian Wolff wrote:
> Hello,
> 
> I noticed that missing debug symbols can cause a huge slow-down in
> libunwind. The same ip will be looked up in dwarf_find_proc_info quite
> often. A log file of a few seconds of runtime show e.g.:
> 
> ...
>     107 IP=0x7f9ba837eaf6 not found
>     122 IP=0x7f9c2832f4cf not found
>     229 IP=0x7f9ba8309233 not found
>     229 IP=0x7f9ba830d9f9 not found
>     306 IP=0xfffeffffffffffff not found
>     319 IP=0x7f9ba760004f not found
>     389 IP=0x7f9c2832fe6f not found
>     392 IP=0x7f9ba7e7ffff not found
>     475 IP=0x7f9ba7f0304f not found
> 
> Is there a reason why this is result is not negative-cached? Are there cases
> where a negative result could theoretically become positive in the future?

Ah, apparently the cache must be put into dwarf_find_save_locs in Gparser.c. 
Any suggestions on how to do this? My naive approach is as follows:

diff --git a/include/dwarf.h b/include/dwarf.h
index 4ec172e..f98d898 100644
--- a/include/dwarf.h
+++ b/include/dwarf.h
@@ -260,6 +260,7 @@ typedef struct dwarf_reg_state
     unsigned short hint;             /* hint for next rs to try (or -1) */
     unsigned short valid : 1;         /* optional machine-dependent signal 
info */
     unsigned short signal_frame : 1;  /* optional machine-dependent signal 
info */
+    unsigned short failed : 1;
   }
 dwarf_reg_state_t;
 
diff --git a/src/dwarf/Gparser.c b/src/dwarf/Gparser.c
index fefd809..50cd3ab 100644
--- a/src/dwarf/Gparser.c
+++ b/src/dwarf/Gparser.c
@@ -882,13 +882,9 @@ dwarf_find_save_locs (struct dwarf_cursor *c)
     }
   else
     {
-      if ((ret = fetch_proc_info (c, c->ip, 1)) < 0 ||
-         (ret = create_state_record_for (c, &sr, c->ip)) < 0)
-       {
-          put_rs_cache (c->as, cache, &saved_mask);
-          put_unwind_info (c, &c->pi);
-         return ret;
-       }
+      ret = fetch_proc_info (c, c->ip, 1);
+      if (ret >= 0)
+       ret = create_state_record_for (c, &sr, c->ip);
 
       rs = rs_new (cache, c);
       memcpy(rs, &sr.rs_current, offsetof(struct dwarf_reg_state, ip));
@@ -898,12 +894,19 @@ dwarf_find_save_locs (struct dwarf_cursor *c)
       c->prev_rs = rs - cache->buckets;
 
       put_unwind_info (c, &c->pi);
+      if (ret < 0) {
+        rs->failed = 1;
+      }
     }
 
   memcpy (&rs_copy, rs, sizeof (rs_copy));
   put_rs_cache (c->as, cache, &saved_mask);
 
   tdep_reuse_frame (c, &rs_copy);
+
+  if (rs_copy.failed)
+    return -UNW_ENOINFO;
+
   if ((ret = apply_reg_state (c, &rs_copy)) < 0)
     return ret;
 
Does that sound OK?

Bye
-- 
Milian Wolff
address@hidden
http://milianw.de



reply via email to

[Prev in Thread] Current Thread [Next in Thread]