[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