From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 28211 invoked by alias); 21 Jul 2010 19:02:43 -0000 Received: (qmail 26188 invoked by uid 48); 21 Jul 2010 19:02:27 -0000 Date: Wed, 21 Jul 2010 19:02:00 -0000 Message-ID: <20100721190227.26187.qmail@sourceware.org> From: "mjw at redhat dot com" To: systemtap@sources.redhat.com In-Reply-To: <20090612210608.10272.mjw@redhat.com> References: <20090612210608.10272.mjw@redhat.com> Reply-To: sourceware-bugzilla@sourceware.org Subject: [Bug runtime/10272] backtraces fail with 32-on-64 executables X-Bugzilla-Reason: AssignedTo Mailing-List: contact systemtap-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Post: List-Help: , Sender: systemtap-owner@sourceware.org X-SW-Source: 2010-q3/txt/msg00095.txt.bz2 ------- Additional Comments From mjw at redhat dot com 2010-07-21 19:02 ------- The original unwinder was written for in-kernel unwinding, so it hard codes assumptions about register wides. The reg_info struct that defines the knowledge about offsets and widths of registers is defined in runtime/unwind/unwind.h. This file includes an architecture specific header file (only i386.h and x86_64.h) that defines the actual UNW_REGISTER_INFO used. Make sure to check the EXTRA_INFO and PTREGS_INFO defines in unwind.h that extract the information as compile time constants from architecture struct pt_regs in the unwind_frame_info struct. The unwinder works by initializing a architecture specific struct unwind_frame_info with a pt_regs struct which the unwinder then adjusts to show the state for previous frame (you can then feed that back into the unwinder to unwind further). The runtime/unwinder.c has some "sanity checks" like: unsigned long value = 0; #ifdef CONFIG_64BIT BUILD_BUG_ON(sizeof(u64) != sizeof(value)); #else BUILD_BUG_ON(sizeof(u32) != sizeof(value)); #endif And checks for registers widths like: if (reg_info[retAddrReg].width != sizeof(unsigned long)) goto err; It als uses compile time constant sizeofs to initialize and copy stuff: memcpy(&state->cfa, &badCFA, sizeof(state->cfa)); memset(state->regs, 0, sizeof(state->regs)); tableSize = sizeof(unsigned long); To update the actual registers it has code like: #define FRAME_REG(r, t) (((t *)frame)[reg_info[r].offs]) #ifndef CONFIG_64BIT # define CASES CASE(8); CASE(16); CASE(32) #else # define CASES CASE(8); CASE(16); CASE(32); CASE(64) #endif case Register: switch (reg_info[i].width) { #define CASE(n) case sizeof(u##n): \ FRAME_REG(i, u##n) = state.regs[i].value; \ break CASES; #undef CASE -- http://sourceware.org/bugzilla/show_bug.cgi?id=10272 ------- You are receiving this mail because: ------- You are the assignee for the bug, or are watching the assignee.