Message ID | DEC42497C6A9034CAD2685219EF0AD2CF57CCB@DEFTHW99EH4MSX.ww902.siemens.net |
---|---|
State | New, archived |
Headers |
Received: (qmail 22908 invoked by alias); 30 Jul 2018 13:10:16 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: <gdb-patches.sourceware.org> List-Unsubscribe: <mailto:gdb-patches-unsubscribe-##L=##H@sourceware.org> List-Subscribe: <mailto:gdb-patches-subscribe@sourceware.org> List-Archive: <http://sourceware.org/ml/gdb-patches/> List-Post: <mailto:gdb-patches@sourceware.org> List-Help: <mailto:gdb-patches-help@sourceware.org>, <http://sourceware.org/ml/#faqs> Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 22891 invoked by uid 89); 30 Jul 2018 13:10:15 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-23.2 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, HTML_MESSAGE, KAM_LAZY_DOMAIN_SECURITY autolearn=ham version=3.3.2 spammy=exported, Definition, mozilla, 23454 X-HELO: goliath.siemens.de Received: from goliath.siemens.de (HELO goliath.siemens.de) (192.35.17.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 30 Jul 2018 13:10:12 +0000 Received: from mail1.sbs.de (mail1.sbs.de [192.129.41.35]) by goliath.siemens.de (8.15.2/8.15.2) with ESMTPS id w6UDA8Zf012836 (version=TLSv1.2 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for <gdb-patches@sourceware.org>; Mon, 30 Jul 2018 15:10:08 +0200 Received: from DEFTHW99ERGMSX.ww902.siemens.net (defthw99ergmsx.ww902.siemens.net [139.22.70.132]) by mail1.sbs.de (8.15.2/8.15.2) with ESMTPS id w6UD9tre031134 (version=TLSv1.2 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for <gdb-patches@sourceware.org>; Mon, 30 Jul 2018 15:10:08 +0200 Received: from DEFTHW99ERFMSX.ww902.siemens.net (139.22.70.67) by DEFTHW99ERGMSX.ww902.siemens.net (139.22.70.132) with Microsoft SMTP Server (TLS) id 14.3.408.0; Mon, 30 Jul 2018 15:10:02 +0200 Received: from DEFTHW99EH4MSX.ww902.siemens.net ([169.254.2.99]) by DEFTHW99ERFMSX.ww902.siemens.net ([139.22.70.67]) with mapi id 14.03.0408.000; Mon, 30 Jul 2018 15:10:02 +0200 From: "Mangold, Kevin" <kevin.mangold@siemens.com> To: "gdb-patches@sourceware.org" <gdb-patches@sourceware.org> Subject: [PATCH] [PR gdb/23454] thread number ID changes, when using rr record/replay Date: Mon, 30 Jul 2018 13:10:01 +0000 Message-ID: <DEC42497C6A9034CAD2685219EF0AD2CF57CCB@DEFTHW99EH4MSX.ww902.siemens.net> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable |
Commit Message
Mangold, Kevin
July 30, 2018, 1:10 p.m. UTC
From 6756339645bf1f4caa31ff8ba3746864c84f3ac7 Mon Sep 17 00:00:00 2001
From: Mangold <kevin.mangold@siemens.com>
Date: Mon, 30 Jul 2018 14:53:43 +0200
Subject: [PATCH] Add ability to track over thread ID's when gdb is used with
rr: https://rr-project.org/
This commit enables the ability to use gdb with rr and rr in eclipse.
Fixes Bug 23454 on Bugzilla
When replaying a thread creation gdb increments the thread ID number
shown with 'info threads'. This caused different thread ID's,
while replaying the same thread exectuion.
In thread.c, we made a change that looks, if this thread already
got a number and if yes, the thread gets the old number assigned.
When using in eclipse, we have to manually increment the
'highest_thread_num' once. Therefore the command:
'rr_running_under_eclipse' was added, which can be used 'once'
to set the correct highest_thread_num.
gdb/ChangeLog:
* thread.c: Add command
---
gdb/thread.c | 153 ++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 152 insertions(+), 1 deletion(-)
this->global_num = ++highest_thread_num;
this->per_inf_num = ++inf_->highest_thread_num;
// add new thread to map
- map.ptid = this->ptid;
+ map.ptid = ptid_;
map.global_num = this->global_num;
map.per_inf_num = this->per_inf_num;
all_existed_threads_list.push_back(map);
@@ -1891,6 +1892,144 @@ thread_name_command (const char *arg, int from_tty)
info->name = arg ? xstrdup (arg) : NULL;
}
+static void
+change_thread_id_1 (const std::string s1, const std::string s2)
+{
+ struct thread_info *thr;
+ update_thread_list();
+
+ bool found_id_1 = false;
+ bool empty_id_2 = true;
+ // check if old id exists and new id does not
+ ALL_THREADS(thr)
+ {
+ std::string s_to_comp ("");
+ if (show_inferior_qualified_tids())
+ {
+ std::stringstream ss;
+ ss << thr->inf->num << "." << thr->per_inf_num;
+ s_to_comp = ss.str();
+ //printf("%s\n", s_to_comp.c_str());
+ }
+ else
+ {
+ std::stringstream ss;
+ ss << thr->per_inf_num;
+ s_to_comp = ss.str();
+ //printf("%s\n", s_to_comp.c_str());
+ }
+ if (s1.compare(s_to_comp) == 0)
+ found_id_1 = true;
+ if (s2.compare(s_to_comp) == 0)
+ empty_id_2 = false;
+ }
+
+ if (found_id_1 && empty_id_2)
+ {
+ // change thread id
+ ALL_THREADS(thr)
+ {
+ std::string s_to_comp ("");
+ if (show_inferior_qualified_tids())
+ {
+ std::stringstream ss;
+ ss << thr->inf->num << "." << thr->per_inf_num;
+ s_to_comp = ss.str();
+ if (s1.compare(s_to_comp) == 0)
+ {
+ int pos = s2.find(".");
+ if(pos!=std::string::npos)
+ {
+ std::string subs1 = s2.substr(0, pos);
+ std::string subs2 = s2.substr(pos+1, s2.size());
+ thr->inf->num = atoi(subs1.c_str());
+ thr->per_inf_num = atoi(subs2.c_str());
+ break;
+ }
+ else
+ error (_("Unexpected error!"));
+ }
+ }
+ else
+ {
+ std::stringstream ss;
+ ss << thr->per_inf_num;
+ s_to_comp = ss.str();
+ if (s1.compare(s_to_comp) == 0)
+ {
+ thr->per_inf_num = atoi(s2.c_str());
+ break;
+ }
+ }
+ }
+ return;
+ }
+ else if(!found_id_1)
+ error (_("<old_id> does not exist!"));
+ else if(!empty_id_2)
+ error (_("<new_id> already exists!"));
+ else
+ error (_("Unexpected error!"));
+}
+
+static void
+change_thread_id (const char *arg, int from_tty)
+{
+ if (arg == NULL || *arg == '\0')
+ error (_("Command requires arguments."));
+
+ std::string s(arg);
+ int c = std::count(s.begin(), s.end(), ' ');
+ if(c!=1)
+ error (_("Usage: <old_ID> <new_ID>"));
+
+ int p = s.find(" ");
+ if(p!=std::string::npos)
+ {
+ // build two substrings
+ std::string s1 = s.substr(0,p);
+ std::string s2 = s.substr(p+1,s.size());
+ regex_t r1;
+ regex_t r2;
+ regmatch_t matches[1];
+
+ //compare if the strings are regular values for thread ID's
+ if (regcomp(&r1, "(^[0-9]+\\.[0-9]+$)", REG_EXTENDED != 0))
+ error (_("Unexpected Error"));
+ if (regcomp(&r2, "(^[0-9]+$)", REG_EXTENDED != 0))
+ error (_("Unexpected Error"));
+
+ int status[2][2];
+ status[0][0] = regexec(&r1, s1.c_str(), 1, matches, 0);
+ status[0][1] = regexec(&r2, s1.c_str(), 1, matches, 0);
+ if (status[0][0] != 0 && status[0][1] != 0)
+ error (_("Usage: <old_ID> <new_ID>"));
+ status[1][0] = regexec(&r1, s2.c_str(), 1, matches, 0);
+ status[1][1] = regexec(&r2, s2.c_str(), 1, matches, 0);
+ if (status[1][0] != 0 && status[1][1] != 0)
+ error (_("Usage: <old_ID> <new_ID>"));
+ regfree(&r1);
+ regfree(&r2);
+
+ // all values are regular,
+ // now we look if both values match the same pattern
+ if(status[0][0] == status[1][0] && status[0][1] == status[1][1])
+ {
+ change_thread_id_1(s1, s2);
+ }
+ else
+ error (_("Thread ID's have not the correct pattern!"));
+ }
+}
+
+static void
+rr_running_under_eclipse (const char *arg, int from_tty)
+{
+ ++highest_thread_num;
+ struct inferior *inf_ = find_inferior_ptid (inferior_ptid);
+ ++inf_->highest_thread_num;
+}
+
/* Find thread ids with a name, target pid, or extra info matching ARG. */
static void
@@ -2165,6 +2304,18 @@ shortcut for 'thread apply all -s frame apply all -s COMMAND'"));
Usage: thread name [NAME]\n\
If NAME is not given, then any existing name is removed."), &thread_cmd_list);
+ add_cmd("change_ID", class_run, change_thread_id, _("\
+Change a existing thread ID with a non-existing thread ID.\n\
+Usage: thread change_ID <old_ID> <new_ID>\n\
+Used by record/replay debuggers to control the replayed thread ID's."), &thread_cmd_list);
+
+ add_cmd("rr_running_under_eclipse", class_run, rr_running_under_eclipse, _("\
+Call this function, when the debugger is used with rr \n\
+(record/replay from https://github.com/mozilla/rr ).\n\
+rr calls this function automated, when used correct with eclipse, \n\
+more Information: https://github.com/mozilla/rr/wiki/Using-rr-in-an-IDE \n\
+Do not use this function manual!"), &cmdlist);
+
add_cmd ("find", class_run, thread_find_command, _("\
Find threads that match a regular expression.\n\
Usage: thread find REGEXP\n\
--
2.17.1.windows.2
Comments
>>>>> "Kevin" == Mangold, Kevin <kevin.mangold@siemens.com> writes:
Kevin> This commit enables the ability to use gdb with rr and rr in eclipse.
Kevin> Fixes Bug 23454 on Bugzilla
Kevin> When replaying a thread creation gdb increments the thread ID number
Kevin> shown with 'info threads'. This caused different thread ID's,
Kevin> while replaying the same thread exectuion.
Kevin> In thread.c, we made a change that looks, if this thread already
Kevin> got a number and if yes, the thread gets the old number assigned.
Kevin> When using in eclipse, we have to manually increment the
Kevin> 'highest_thread_num' once. Therefore the command:
Kevin> 'rr_running_under_eclipse' was added, which can be used 'once'
Kevin> to set the correct highest_thread_num.
If I understand properly, what's going on here is that with rr, you can
reverse-step past the creation of a thread. Then, when replaying again,
the thread is recreated but with a new thread id. However, you would
like gdb to preserve the thread id.
I think preserving the thread id makes a lot of sense. However, I don't
think a new magic command like this is the way to go about it.
Would it be possible to record some pertinent information about a thread
when stepping backward, and then maintain a map that is used to reassign
the old thread id when the thread is recreated when moving forward?
Tom
diff --git a/gdb/thread.c b/gdb/thread.c index 7cb618b12e..aadbf935f5 100644 --- a/gdb/thread.c +++ b/gdb/thread.c @@ -45,6 +45,7 @@ #include "tid-parse.h" #include <algorithm> #include <list> +#include <regex> #include "common/gdb_optional.h" /* Definition of struct thread_info exported to gdbthread.h. */ @@ -362,7 +363,7 @@ thread_info::thread_info (struct inferior *inf_, ptid_t ptid_)