From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 7366 invoked by alias); 25 May 2004 07:13:52 -0000 Mailing-List: contact gdb-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-owner@sources.redhat.com Received: (qmail 7281 invoked from network); 25 May 2004 07:13:43 -0000 Received: from unknown (HELO pippin.tausq.org) (64.81.244.94) by sourceware.org with SMTP; 25 May 2004 07:13:43 -0000 Received: by pippin.tausq.org (Postfix, from userid 1000) id C4A7ECD299; Tue, 25 May 2004 00:13:40 -0700 (PDT) Date: Tue, 25 May 2004 07:13:00 -0000 From: Randolph Chung To: Andrew Cagney Cc: gdb@sources.redhat.com Subject: Re: [patch/rfc] How to handle stepping into an unresolved plt entry? Message-ID: <20040525071340.GE7207@tausq.org> Reply-To: Randolph Chung References: <20040521064435.GJ566@tausq.org> <40AE27AC.6090205@gnu.org> <20040521182138.GN566@tausq.org> <40B231BE.50609@gnu.org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <40B231BE.50609@gnu.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/msg00161.txt.bz2 > The rationale (if we think it can be called that :-) is lost in the > depths of time. Perhaps some unwinders barfed when presented with a > function with no function name so it was thought that doing the check > first was prudent? > > Anyway, can the IN_SOLIB_RETURN_TRAMPOLINE be moved up as well (with an > additional ecs->stop_func_name != NULL check? The attached patch contains the new arrangement of tests that works better on hppa. Regression tested on i386-linux. I'd be interested to see test results for some of the ppc variants, since they seem to be also have interesting trampoline code. Also, some comments from looking at the 2nd half of handle_inferior_event (stepping out of stepping range).... the new order of cases being handled is: 1. Runtime loader 2. Signal trampoline 3. current frame == step frame 3a. stepi/nexti-in-prologue 3b. next/IGNORE_HELPER_CALL check 3c. skip trampolines 3d. Runtime loader check 3e. If line number available at target, step into function else put breakpoint in previous frame and continue 4. Return trampoline 5. Stopped at function with no name 6. stepi/nexti 7. No line number info 8. Stepped to next line 9. Stepped out of current function 10. Update current frame and continue Several questions: - At step 3: if (frame_id_eq (frame_unwind_id (get_current_frame ()), step_frame_id)) { /* It's a subroutine call. */ Why is this "a subroutine call"? It seems that in the general case this is not a subroutine call..... - At step 3b, IGNORE_HELPER_CALL () is only defined for mips. The comments say: /* On MIPS16, a function that returns a floating point value may call a library helper function to copy the return value to a floating point register. The IGNORE_HELPER_CALL macro returns non-zero if we should ignore (i.e. step over) this function call. */ Shouldn't this be handled by the trampoline logic? I guess this might be historical... At step 5: we declare the function as "undebuggable" if it has no name, but elsewhere in this function it seems to equate "undebuggable" with "no line number" in a sal lookup.... are both tests needed, or is 5/7 redundant? Other comments? thanks, randolph -- Randolph Chung Debian GNU/Linux Developer, hppa/ia64 ports http://www.tausq.org/ 2004-05-24 Randolph Chung * infrun.c (handle_inferior_event): Handle the case when a trampoline ends up in the runtime resolver, and if the trampoline has no name. Rearrange the code so that all the trampoline processing happens before other step-out-of-range handling. Index: infrun.c =================================================================== RCS file: /cvs/src/src/gdb/infrun.c,v retrieving revision 1.163 diff -u -p -r1.163 infrun.c --- infrun.c 14 May 2004 18:45:42 -0000 1.163 +++ infrun.c 25 May 2004 06:33:51 -0000 @@ -2344,36 +2344,6 @@ process_event_stop_test: return; } - if (step_over_calls == STEP_OVER_UNDEBUGGABLE - && ecs->stop_func_name == NULL) - { - /* The inferior just stepped into, or returned to, an - undebuggable function (where there is no symbol, not even a - minimal symbol, corresponding to the address where the - inferior stopped). Since we want to skip this kind of code, - we keep going until the inferior returns from this - function. */ - if (step_stop_if_no_debug) - { - /* If we have no line number and the step-stop-if-no-debug - is set, we stop the step so that the user has a chance to - switch in assembly mode. */ - stop_step = 1; - print_stop_reason (END_STEPPING_RANGE, 0); - stop_stepping (ecs); - return; - } - else - { - /* Set a breakpoint at callee's return address (the address - at which the caller will resume). */ - insert_step_resume_breakpoint (get_prev_frame (get_current_frame ()), - ecs); - keep_going (ecs); - return; - } - } - if (frame_id_eq (frame_unwind_id (get_current_frame ()), step_frame_id)) { @@ -2418,6 +2388,22 @@ process_event_stop_test: if (real_stop_pc != 0) ecs->stop_func_start = real_stop_pc; + if (IN_SOLIB_DYNSYM_RESOLVE_CODE (ecs->stop_func_start)) + { + struct symtab_and_line sr_sal; + init_sal (&sr_sal); + sr_sal.pc = ecs->stop_func_start; + + check_for_old_step_resume_breakpoint (); + step_resume_breakpoint = + set_momentary_breakpoint (sr_sal, null_frame_id, bp_step_resume); + if (breakpoints_inserted) + insert_breakpoints (); + + keep_going (ecs); + return; + } + /* If we have line number information for the function we are thinking of stepping into, step into it. @@ -2453,20 +2439,6 @@ process_event_stop_test: return; } - /* We've wandered out of the step range. */ - - ecs->sal = find_pc_line (stop_pc, 0); - - if (step_range_end == 1) - { - /* It is stepi or nexti. We always want to stop stepping after - one instruction. */ - stop_step = 1; - print_stop_reason (END_STEPPING_RANGE, 0); - stop_stepping (ecs); - return; - } - /* If we're in the return path from a shared library trampoline, we want to proceed through the trampoline when stepping. */ if (IN_SOLIB_RETURN_TRAMPOLINE (stop_pc, ecs->stop_func_name)) @@ -2498,6 +2470,51 @@ process_event_stop_test: return; } } + + /* NOTE: tausq/2004-05-24: This if block used to be done before all + the trampoline processing logic, however, there are some trampolines + that have no names, so we should do trampoline handling first. */ + if (step_over_calls == STEP_OVER_UNDEBUGGABLE + && ecs->stop_func_name == NULL) + { + /* The inferior just stepped into, or returned to, an + undebuggable function (where there is no symbol, not even a + minimal symbol, corresponding to the address where the + inferior stopped). Since we want to skip this kind of code, + we keep going until the inferior returns from this + function. */ + if (step_stop_if_no_debug) + { + /* If we have no line number and the step-stop-if-no-debug + is set, we stop the step so that the user has a chance to + switch in assembly mode. */ + stop_step = 1; + print_stop_reason (END_STEPPING_RANGE, 0); + stop_stepping (ecs); + return; + } + else + { + /* Set a breakpoint at callee's return address (the address + at which the caller will resume). */ + insert_step_resume_breakpoint (get_prev_frame (get_current_frame ()), + ecs); + keep_going (ecs); + return; + } + } + + if (step_range_end == 1) + { + /* It is stepi or nexti. We always want to stop stepping after + one instruction. */ + stop_step = 1; + print_stop_reason (END_STEPPING_RANGE, 0); + stop_stepping (ecs); + return; + } + + ecs->sal = find_pc_line (stop_pc, 0); if (ecs->sal.line == 0) {