From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 26860 invoked by alias); 16 Dec 2013 20:30:30 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 26767 invoked by uid 89); 16 Dec 2013 20:30:29 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.8 required=5.0 tests=AWL,BAYES_00,RP_MATCHES_RCVD,SPF_HELO_PASS,SPF_PASS autolearn=ham version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 16 Dec 2013 20:30:27 +0000 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id rBGKUIYB018310 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Mon, 16 Dec 2013 15:30:22 -0500 Received: from [127.0.0.1] (ovpn01.gateway.prod.ext.ams2.redhat.com [10.39.146.11]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id rBGKU30V016567; Mon, 16 Dec 2013 15:30:04 -0500 Message-ID: <52AF62CB.7010805@redhat.com> Date: Mon, 16 Dec 2013 20:30:00 -0000 From: Pedro Alves User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130625 Thunderbird/17.0.7 MIME-Version: 1.0 To: "Metzger, Markus T" CC: "jan.kratochvil@redhat.com" , "gdb-patches@sourceware.org" , Eli Zaretskii Subject: Re: [patch v8 24/24] record-btrace: add (reverse-)stepping support References: <1386839747-8860-1-git-send-email-markus.t.metzger@intel.com> <1386839747-8860-25-git-send-email-markus.t.metzger@intel.com> <52AB5E6A.1010105@redhat.com> In-Reply-To: Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-SW-Source: 2013-12/txt/msg00602.txt.bz2 On 12/16/2013 03:54 PM, Metzger, Markus T wrote: >> -----Original Message----- >> From: Pedro Alves [mailto:palves@redhat.com] >> Sent: Friday, December 13, 2013 8:22 PM > > Thanks for your review. > > >>> + /* Clear the executing flag to allow changes to the current frame. */ >>> + executing = is_executing (tp->ptid); >>> + set_executing (tp->ptid, 0); >> >> Why is this necessary? Is this so you can start replaying >> even when the current thread is really executing? > > No. When we just start replaying with a reverse stepping command, > we need to recompute stack frames so we can compare them to > detect subroutine calls in infrun.c. > > See also https://sourceware.org/ml/gdb-patches/2013-11/msg00874.html > and https://sourceware.org/ml/gdb-patches/2013-11/msg00891.html. I guess this goes in a similar direction of what I was asking in the other thread. When we enable replaying, is still sitting at the same location the live inferior is, it seems like if you allow reading registers/memory from the live inferior, then you can also use the regular dwarf unwinder for that frame, and then you wouldn't need to frob step_frame_id, etc. > > This function is called from to_wait to enable replaying as part of > reverse stepping. We need to temporarily set is_executing to false > in order to be able to call get_current_frame below. Ah, because target_set called set_executing (..., 1), right? I forgot record full does something like that too. > > I extended the existing comments here and below to explain this in more detail. > >>> + /* Restore the previous execution state. */ >>> + set_executing (tp->ptid, executing); >>> + >>> + if (except.reason < 0) >>> + throw_exception (except); >> >> If something throws, things are being left >> possibly in an inconsistent state, it seems to me. >> Also, "replay" leaks. > > Replay is stored in BTINFO. We checked that we have trace before > the try block, so btrace_insn_end () won't throw and we're not > leaking REPLAY - we just transitioned from not replaying to replaying. > > It may still be better to revert the changes and not start replaying > in case of errors. Changed that. I'm also calling registers_changed_ptid > and get_current_frame again to avoid leaving things behind that are > based on replaying. This might trigger another throw. Sounds good, thanks. >>> + if (tp != NULL && !btrace_is_replaying (tp) >>> + && execution_direction != EXEC_REVERSE) >>> + ALL_THREADS (other) >>> + record_btrace_stop_replaying (other); >> >> Why's that? > > Imagine the user does: > > (gdb) thread 1 > (gdb) reverse-steop > (gdb) thread 2 > (gdb) record goto 42 > (gdb) thread 3 > (gdb) continue > > We could either error out and make him go to thread 1 and thread 2 > again to stop replaying those threads. Or we could more or less > silently stop replaying those other threads before we continue. > > I chose to silently stop replaying; no warnings and no questions. > I find both somewhat annoying after some time. Hmm. I see. Please consider scheduler-locking though. That is, (gdb) set scheduler-locking on (gdb) thread 1 (gdb) reverse-steop (gdb) thread 2 (gdb) record goto 42 (gdb) thread 3 (gdb) continue The last continue doesn't apply to threads 1 and 2, so not clear what it should do to them then. My knee jerk would be to leave them alone. > > >>> + /* Find the thread to move. */ >>> + if (ptid_equal (minus_one_ptid, ptid) || ptid_is_pid (ptid)) >>> + { >>> + ALL_THREADS (tp) >>> + record_btrace_resume_thread (tp, flag); >> >> Seems like this steps all threads, when gdb only wants to >> step inferior_ptid and continue others? > > Only if gdb passes -1 or the ptid of the process. Yes, but -1 or "ptid of the process" means "step inferior_ptid and let others run free". > In the end, we will move exactly one thread and keep all > others where they are. This one thread will hit a breakpoint > or run out of execution history. Some of the other threads can hit a breakpoint before the current thread hits one too. > Are you suggesting that I should only mark inferior_ptid > in this case? If I marked the others as continue, I would later > on need to prefer a thread that only wanted to step. > > I'm preferring inferior_ptid in to_wait later on when the > threads are actually moved. The effect should be the same, > but it might be more clear if I also did not mark the other > threads. It's better to not rely on inferior_ptid in to_wait at all. E.g., in non-stop/async (I now you don't support it now, but still), there's no connection between inferior_ptid and the thread that was stepped when you get to target_wait. It really can't --- in principle, how could core GDB know which thread would get the event _before_ the target reported it to the core exactly with target_wait ? > > >>> + if (breakpoint_here_p (aspace, insn->pc)) >>> + return btrace_step_stopped (); >> >> How is adjust_pc_after_break handled? > > I'm not doing anything special. The PC register is writable, > so the PC can be adjusted. Eh, it's writable even when forward executing through history? I see this in patch 14: > +static void > +record_btrace_store_registers (struct target_ops *ops, > + struct regcache *regcache, int regno) > +{ > + struct target_ops *t; > + > + if (record_btrace_is_replaying ()) > + error (_("This record target does not allow writing registers.")); > + Was it changed in later patches? >>> +# navigate in the trace history for both threads >>> +gdb_test "thread 1" ".*" "mts, 1.1" >>> +gdb_test "record goto begin" ".*" "mts, 1.2" >>> +gdb_test "info record" ".*Replay in progress\. At instruction 1\." "mts, >> 1.3" >>> +gdb_test "thread 2" ".*" "mts, 1.4" >>> +gdb_test "record goto begin" ".*" "mts, 1.5" >>> +gdb_test "info record" ".*Replay in progress\. At instruction 1\." "mts, >> 1.6" >> >> What does this "mts" that appears everywhere mean? >> (with_test_prefix could help here to create more meaningful test names.) > > It's a simple tag so I find the failing test quickly. Right, I was just wondering what is stood for -- "Markus T ...", I guess? > > With_test_prefix wouldn't really help. I could use "mts, " as test prefix, but > this would leave the raw numbers "1.1", "1.2", ... in the tests. > I don't really need the prefix since the failing .exp file is already included > in the fail message. If it is confusing, I might as well omit it and use the numbers > only. I meant things like: # navigate in the trace history for both threads with_test_prefix "nativ-hist-both-thrds" { gdb_test "thread 1" ".*" with_test_prefix "thrd1" { gdb_test "record goto begin" ".*" gdb_test "info record" ".*Replay in progress\. At instruction 1\." } gdb_test "thread 2" ".*" with_test_prefix "thrd2" { gdb_test "record goto begin" ".*" gdb_test "info record" ".*Replay in progress\. At instruction 1\." } } This way you don't need numbers at all, and gdb.sum shows something meaningful (if not specified, the gdb.sum out defaults to the gdb command passed to gdb_test). Some of the old gdb.trace/ tests also used numbers like this, and over time, was we add/remove bits from the tests, we end up with outdated numbers, holes in the numeric sequence, etc. Sometimes you need to update the numbers of the following tests to make room for one other tests. Etc. -- Pedro Alves