[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Libunwind-devel] [PATCH 4/6] Workaround for old FreeBSD kernels not und
From: |
Konstantin Belousov |
Subject: |
[Libunwind-devel] [PATCH 4/6] Workaround for old FreeBSD kernels not understanding tid for procinfo sysctls. |
Date: |
Mon, 23 Apr 2012 13:29:00 +0300 |
Older kernels interpret the pid argument of the process information
sysctls as pid only. If libunwind UPT consumer passed tid to _UPT_create,
tdep_get_elf_image() returns error due to sysctls failure. Provide a
slow workaround by searching for a process owning the supplied tid
if sysctl returned ESRCH.
---
src/os-freebsd.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 50 insertions(+), 2 deletions(-)
diff --git a/src/os-freebsd.c b/src/os-freebsd.c
index 203347e..76cdd23 100644
--- a/src/os-freebsd.c
+++ b/src/os-freebsd.c
@@ -28,6 +28,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. */
#include <sys/sysctl.h>
#include <sys/user.h>
#include <stdio.h>
+#include <errno.h>
#include "libunwind_i.h"
@@ -48,6 +49,45 @@ free_mem(void *ptr, size_t sz)
munmap(ptr, sz);
}
+static int
+get_pid_by_tid(int tid)
+{
+ int mib[3], error;
+ size_t len, len1;
+ char *buf;
+ struct kinfo_proc *kv;
+ int i, pid;
+
+ len = 0;
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_PROC;
+ mib[2] = KERN_PROC_ALL;
+
+ error = sysctl(mib, 3, NULL, &len, NULL, 0);
+ if (error == -1)
+ return (-1);
+ len1 = len * 4 / 3;
+ buf = get_mem(len1);
+ if (buf == NULL)
+ return (-1);
+ len = len1;
+ error = sysctl(mib, 3, buf, &len, NULL, 0);
+ if (error == -1) {
+ free_mem(buf, len1);
+ return (-1);
+ }
+ pid = -1;
+ for (i = 0, kv = (struct kinfo_proc *)buf; i < len / sizeof(*kv);
+ i++, kv++) {
+ if (kv->ki_tid == tid) {
+ pid = kv->ki_pid;
+ break;
+ }
+ }
+ free_mem(buf, len1);
+ return (pid);
+}
+
PROTECTED int
tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip,
unsigned long *segbase, unsigned long *mapoff, char *path,
size_t pathlen)
@@ -64,8 +104,16 @@ tdep_get_elf_image (struct elf_image *ei, pid_t pid,
unw_word_t ip,
mib[3] = pid;
error = sysctl(mib, 4, NULL, &len, NULL, 0);
- if (error)
- return (-1);
+ if (error == -1) {
+ if (errno == ESRCH) {
+ mib[3] = get_pid_by_tid(pid);
+ if (mib[3] != -1)
+ error = sysctl(mib, 4, NULL, &len, NULL, 0);
+ if (error == -1)
+ return (-UNW_EUNSPEC);
+ } else
+ return (-UNW_EUNSPEC);
+ }
len1 = len * 4 / 3;
buf = get_mem(len1);
if (buf == NULL)
--
1.7.9.6
- [Libunwind-devel] [PATCH 4/6] Workaround for old FreeBSD kernels not understanding tid for procinfo sysctls., (continued)
- [Libunwind-devel] [PATCH 4/6] Workaround for old FreeBSD kernels not understanding tid for procinfo sysctls., Konstantin Belousov, 2012/04/23
- [Libunwind-devel] [PATCH 3/6] Fix logic error. When encountered vm map entry is not backed by a vnode, continue search for matching entry instead of aborting the loop., Konstantin Belousov, 2012/04/23
- [Libunwind-devel] [PATCH 6/6] Fixes for interation end conditions of non-dwarf walker on x86_64., Konstantin Belousov, 2012/04/23
- [Libunwind-devel] [PATCH 5/6] Account for the possible ERESTART handling of the syscalls., Konstantin Belousov, 2012/04/23
- [Libunwind-devel] [PATCH 0/6] FreeBSD improvements, Konstantin Belousov, 2012/04/23
- [Libunwind-devel] [PATCH 3/6] Fix logic error. When encountered vm map entry is not backed by a vnode, continue search for matching entry instead of aborting the loop., Konstantin Belousov, 2012/04/23
- [Libunwind-devel] [PATCH 1/6] Compare current sigset with the sigset saved right before _setjmp() call., Konstantin Belousov, 2012/04/23
- [Libunwind-devel] [PATCH 5/6] Account for the possible ERESTART handling of the syscalls., Konstantin Belousov, 2012/04/23
- [Libunwind-devel] [PATCH 2/6] Consistently use symbolic name UNW_EUNSPEC for error code instead of hard-coding -1., Konstantin Belousov, 2012/04/23
- [Libunwind-devel] [PATCH 6/6] Fixes for interation end conditions of non-dwarf walker on x86_64., Konstantin Belousov, 2012/04/23
- [Libunwind-devel] [PATCH 4/6] Workaround for old FreeBSD kernels not understanding tid for procinfo sysctls.,
Konstantin Belousov <=