From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 889 invoked by alias); 7 May 2004 15:07:57 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 880 invoked from network); 7 May 2004 15:07:55 -0000 Received: from unknown (HELO pippin.tausq.org) (64.81.244.94) by sources.redhat.com with SMTP; 7 May 2004 15:07:55 -0000 Received: by pippin.tausq.org (Postfix, from userid 1000) id A464FCD28A; Fri, 7 May 2004 08:07:58 -0700 (PDT) Date: Fri, 07 May 2004 15:07:00 -0000 From: Randolph Chung To: Andrew Cagney Cc: gdb-patches@sources.redhat.com Subject: Re: [patch] sigaltstack fixes for hppa-linux Message-ID: <20040507150758.GJ3965@tausq.org> Reply-To: Randolph Chung References: <20040504150219.GJ3965@tausq.org> <409A92F0.2050209@gnu.org> <20040507023627.GG3965@tausq.org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20040507023627.GG3965@tausq.org> X-GPG: for GPG key, see http://www.tausq.org/gpg.txt User-Agent: Mutt/1.5.5.1+cvs20040105i X-SW-Source: 2004-05/txt/msg00198.txt.bz2 > well, only because the hppa sigtramp unwinder is slightly broken :-) for > the sigtramp frame it current uses the sp stored in the sigcontext as > the frame base. instead it should probably use the handler's stack. here's a fixed version. No frame.c modifications needed :) one question related to this: i noticed that some of the tests are failing when: - a breakpoint is placed in the signal trampoline (e.g. "finish" from the signal handler) - we try to unwind from the signal trampoline frame they fail because breakpoints are not yet disabled when the unwinding starts (get_frame_id() is called early on in handle_inferior_event, which runs through the unwinders) Are the unwinders that do code matching supposed to deal with the case where there are breakpoints inserted in the code stream? or does this point to something else that is broken? thanks randolph 2004-05-06 Randolph Chung * hppa-linux-tdep.c (hppa_linux_sigtramp_find_sigcontext): Pass in pc instead of sp, handle sigaltstack case. (hppa_linux_sigtramp_frame_unwind_cache): Adjust calls to hppa_linux_sigtramp_find_sigcontext, and set base to the frame of the signal handler and not that of the caller. (hppa_linux_sigtramp_unwind_sniffer): Adjust calls to hppa_linux_sigtramp_find_sigcontext. Index: hppa-linux-tdep.c =================================================================== RCS file: /cvs/src/src/gdb/hppa-linux-tdep.c,v retrieving revision 1.2 diff -u -p -r1.2 hppa-linux-tdep.c --- hppa-linux-tdep.c 7 May 2004 05:48:49 -0000 1.2 +++ hppa-linux-tdep.c 7 May 2004 06:24:07 -0000 @@ -282,7 +284,7 @@ hppa_linux_skip_trampoline_code (CORE_AD Note that with a 2.4 64-bit kernel, the signal context is not properly passed back to userspace so the unwind will not work correctly. */ static CORE_ADDR -hppa_linux_sigtramp_find_sigcontext (CORE_ADDR sp) +hppa_linux_sigtramp_find_sigcontext (CORE_ADDR pc) { unsigned int dummy[HPPA_MAX_INSN_PATTERN_LEN]; int offs = 0; @@ -291,6 +293,12 @@ hppa_linux_sigtramp_find_sigcontext (COR static int pcoffs[] = { 0, 4*4, 5*4 }; /* offsets to the rt_sigframe structure */ static int sfoffs[] = { 4*4, 10*4, 10*4 }; + CORE_ADDR sp; + + /* Most of the time, this will be correct. The one case when this will + fail is if the user defined an alternate stack, in which case the + beginning of the stack will not be pc & 63. */ + sp = (pc & ~63); /* rt_sigreturn trampoline: 3419000x ldi 0, %r25 or ldi 1, %r25 (x = 0 or 2) @@ -308,7 +316,20 @@ hppa_linux_sigtramp_find_sigcontext (COR } if (offs == 0) - return 0; + { + if (insns_match_pattern (pc, hppa_sigtramp, dummy)) + { + /* sigaltstack case: we have no way of knowing which offset to + use in this case; default to new kernel handling. If this is + wrong the unwinding will fail. */ + try = 2; + sp = pc - pcoffs[try]; + } + else + { + return 0; + } + } /* sp + sfoffs[try] points to a struct rt_sigframe, which contains a struct siginfo and a struct ucontext. struct ucontext contains @@ -331,7 +352,7 @@ hppa_linux_sigtramp_frame_unwind_cache ( { struct gdbarch *gdbarch = get_frame_arch (next_frame); struct hppa_linux_sigtramp_unwind_cache *info; - CORE_ADDR sp, pc, scptr; + CORE_ADDR pc, scptr; int i; if (*this_cache) @@ -342,8 +363,7 @@ hppa_linux_sigtramp_frame_unwind_cache ( info->saved_regs = trad_frame_alloc_saved_regs (next_frame); pc = frame_pc_unwind (next_frame); - sp = (pc & ~63); - scptr = hppa_linux_sigtramp_find_sigcontext (sp); + scptr = hppa_linux_sigtramp_find_sigcontext (pc); /* structure of struct sigcontext: @@ -393,8 +413,7 @@ hppa_linux_sigtramp_frame_unwind_cache ( info->saved_regs[HPPA_PCOQ_TAIL_REGNUM].addr = scptr; scptr += 4; - info->base = read_memory_unsigned_integer ( - info->saved_regs[HPPA_SP_REGNUM].addr, 4); + info->base = frame_unwind_register_unsigned (next_frame, HPPA_SP_REGNUM); return info; } @@ -448,14 +458,84 @@ static const struct frame_unwind * hppa_linux_sigtramp_unwind_sniffer (struct frame_info *next_frame) { CORE_ADDR pc = frame_pc_unwind (next_frame); - CORE_ADDR sp = (pc & ~63); - if (hppa_linux_sigtramp_find_sigcontext (sp)) + if (hppa_linux_sigtramp_find_sigcontext (pc)) return &hppa_linux_sigtramp_frame_unwind; return NULL; } /* Forward declarations. */ extern initialize_file_ftype _initialize_hppa_linux_tdep;