>From 2d24d20c70b877da1beab0376fc5234f5399d58a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Richard?= Date: Sun, 2 Oct 2016 04:14:07 +0200 Subject: [PATCH 1/2] Bug 683121 - Adding thread names beside the thread IDs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * src/persp/dbgperspective/nmv-thread-list.cc (struct ThreadListColumns): Added thread_name column. (on_debugger_threads_listed_signal): changed signature to pass the thread name. (build_widget): append the thread_name column. (set_thread_id): changed signature to pass the thread name and add it to the model. (set_thread_id_list): change signature and add thread_name into the list model. * src/dbgengine/nmv-i-debugger.h: change type of threads_listed_signal to match. * src/dbgengine/nmv-gdb-engine.h: change type of threads_listed_signal to match. * src/dbgengine/nmv-gdb-engine.cc: (struct GDBEngine::Prive) change type of threads_listed_signal to match. (GDBEngine::threads_listed_signal): change return type to match. (GDBEngine::list_threads): change call to queue_command to macth. * src/dbgengine/nmv-dbg-common.h (class ResultRecord): change type of m_thread_list to include thread name. (ResultRecord::thread_list): change signature to match new type. * src/dbgengine/nmv-gdbmi-parser.h (parse_threads_list): change signature to match. * src/dbgengine/nmv-gdbmi-parser.cc (PREFIX_THREADS_IDS): change prefix to PREFIX_THREADS for parser. (GDBMIParser::parse_result_record) Now parse PREFIX_THREADS. (GDBMIParser::parse_threads_list) Change signature and parse PREFIX_THREADS. * po/en_GB.po: * po/fr.po: Added "Thread Name" string. Signed-off-by: Hubert Figuière --- po/en_GB.po | 6 +- po/fr.po | 6 +- src/dbgengine/nmv-dbg-common.h | 6 +- src/dbgengine/nmv-gdb-engine.cc | 7 +- src/dbgengine/nmv-gdb-engine.h | 2 +- src/dbgengine/nmv-gdbmi-parser.cc | 130 +++++++++++++++------------- src/dbgengine/nmv-gdbmi-parser.h | 2 +- src/dbgengine/nmv-i-debugger.h | 4 +- src/persp/dbgperspective/nmv-thread-list.cc | 15 ++-- 9 files changed, 104 insertions(+), 74 deletions(-) diff --git a/po/en_GB.po b/po/en_GB.po index b0b5165..ea7e34b 100644 --- a/po/en_GB.po +++ b/po/en_GB.po @@ -959,10 +959,14 @@ msgstr "Vfork System Call" msgid "Exec System Call" msgstr "Exec System Call" -#: ../src/persp/dbgperspective/nmv-thread-list.cc:184 +#: ../src/persp/dbgperspective/nmv-thread-list.cc:186 msgid "Thread ID" msgstr "Thread ID" +#: ../src/persp/dbgperspective/nmv-thread-list.cc:188 +msgid "Thread Name" +msgstr "Thread Name" + #. create the columns of the tree view #: ../src/persp/dbgperspective/nmv-vars-treeview.cc:50 msgid "Variable" diff --git a/po/fr.po b/po/fr.po index 22d0142..04f97ce 100644 --- a/po/fr.po +++ b/po/fr.po @@ -977,10 +977,14 @@ msgstr "Appel système vfork" msgid "Exec System Call" msgstr "Appel système exec" -#: ../src/persp/dbgperspective/nmv-thread-list.cc:184 +#: ../src/persp/dbgperspective/nmv-thread-list.cc:186 msgid "Thread ID" msgstr "ID thread" +#: ../src/persp/dbgperspective/nmv-thread-list.cc:188 +msgid "Thread Name" +msgstr "Nom thread" + #. create the columns of the tree view #: ../src/persp/dbgperspective/nmv-vars-treeview.cc:50 msgid "Variable" diff --git a/src/dbgengine/nmv-dbg-common.h b/src/dbgengine/nmv-dbg-common.h index 13b663b..1be7f25 100644 --- a/src/dbgengine/nmv-dbg-common.h +++ b/src/dbgengine/nmv-dbg-common.h @@ -467,7 +467,7 @@ public: bool m_has_variable_value; //threads listed members - std::list m_thread_list; + std::list> m_thread_list; bool m_has_thread_list; //files listed members @@ -725,8 +725,8 @@ public: bool has_thread_list () const {return m_has_thread_list;} void has_thread_list (bool a_in) {m_has_thread_list = a_in;} - const std::list& thread_list () const {return m_thread_list;} - void thread_list (const std::list &a_in) + const std::list>& thread_list () const {return m_thread_list;} + void thread_list (const std::list> &a_in) { m_thread_list = a_in; has_thread_list (true); diff --git a/src/dbgengine/nmv-gdb-engine.cc b/src/dbgengine/nmv-gdb-engine.cc index 68e181f..a77bff1 100644 --- a/src/dbgengine/nmv-gdb-engine.cc +++ b/src/dbgengine/nmv-gdb-engine.cc @@ -34,6 +34,7 @@ #include #include #include +#include #include "nmv-i-debugger.h" #include "common/nmv-env.h" #include "common/nmv-exception.h" @@ -294,7 +295,7 @@ public: int, const string&, const UString&> stopped_signal; mutable sigc::signal, + const list>, const UString& > threads_listed_signal; mutable sigc::signalstopped_signal; } -sigc::signal, const UString& >& +sigc::signal>, const UString& >& GDBEngine::threads_listed_signal () const { return m_priv->threads_listed_signal; @@ -5199,7 +5200,7 @@ GDBEngine::list_threads (const UString &a_cookie) { LOG_FUNCTION_SCOPE_NORMAL_DD; - queue_command (Command ("list-threads", "-thread-list-ids", a_cookie)); + queue_command (Command ("list-threads", "-thread-info", a_cookie)); } void diff --git a/src/dbgengine/nmv-gdb-engine.h b/src/dbgengine/nmv-gdb-engine.h index 55a6a4d..fcb0966 100644 --- a/src/dbgengine/nmv-gdb-engine.h +++ b/src/dbgengine/nmv-gdb-engine.h @@ -103,7 +103,7 @@ public: const UString& /*cookie*/>& stopped_signal () const; sigc::signal, + const list>, const UString& >& threads_listed_signal () const; sigc::signal&, const UString& >& diff --git a/src/dbgengine/nmv-gdbmi-parser.cc b/src/dbgengine/nmv-gdbmi-parser.cc index d414d5d..13dce77 100644 --- a/src/dbgengine/nmv-gdbmi-parser.cc +++ b/src/dbgengine/nmv-gdbmi-parser.cc @@ -134,7 +134,7 @@ static const char* PREFIX_ERROR = "^error"; static const char* PREFIX_BKPT = "bkpt={"; static const char* PREFIX_BREAKPOINT_TABLE = "BreakpointTable={"; static const char* PREFIX_BREAKPOINT_MODIFIED_ASYNC_OUTPUT = "=breakpoint-modified,"; -static const char* PREFIX_THREAD_IDS = "thread-ids={"; +static const char* PREFIX_THREADS = "threads=["; static const char* PREFIX_NEW_THREAD_ID = "new-thread-id=\""; static const char* PREFIX_FILES = "files=["; static const char* PREFIX_STACK = "stack=["; @@ -1885,9 +1885,9 @@ fetch_gdbmi_result: if (parse_breakpoint_table (cur, cur, breaks)) { result_record.breakpoints () = breaks; } - } else if (!m_priv->input.compare (cur, strlen (PREFIX_THREAD_IDS), - PREFIX_THREAD_IDS)) { - std::list thread_ids; + } else if (!m_priv->input.compare (cur, strlen (PREFIX_THREADS), + PREFIX_THREADS)) { + std::list> thread_ids; if (parse_threads_list (cur, cur, thread_ids)) { result_record.thread_list (thread_ids); } @@ -2546,20 +2546,19 @@ GDBMIParser::parse_breakpoint_modified_async_output (UString::size_type a_from, bool GDBMIParser::parse_threads_list (UString::size_type a_from, UString::size_type &a_to, - std::list &a_thread_ids) + std::list> &a_thread_ids) { LOG_FUNCTION_SCOPE_NORMAL_D (GDBMI_PARSING_DOMAIN); UString::size_type cur = a_from; - if (RAW_INPUT.compare (cur, strlen (PREFIX_THREAD_IDS), - PREFIX_THREAD_IDS)) { + if (RAW_INPUT.compare (cur, strlen (PREFIX_THREADS), + PREFIX_THREADS)) { LOG_PARSING_ERROR (cur); return false; } GDBMIResultSafePtr gdbmi_result; - std::list thread_ids; - unsigned int num_threads = 0; + std::list> threads; // We loop, parsing GDB/MI RESULT constructs and ',' until we reach '\n' while (true) { @@ -2567,55 +2566,79 @@ GDBMIParser::parse_threads_list (UString::size_type a_from, LOG_PARSING_ERROR (cur); return false; } - if (gdbmi_result->variable () == "thread-ids") { - // We've got a RESULT which variable is "thread-ids", we expect - // the value to be tuple of RESULTs of the form - // thread-id="" + + if (gdbmi_result->variable () == "threads") { + // We've got a RESULT which variable is "threads", we expect + // the value to be list of RESULTs which contains tuples of + // the form { + // id="", + // target-id="", + // name="", + // frame=, + // state="", + // core="" + // } THROW_IF_FAIL (gdbmi_result->value ()); THROW_IF_FAIL ((gdbmi_result->value ()->content_type () - == GDBMIValue::TUPLE_TYPE) + == GDBMIValue::LIST_TYPE) || (gdbmi_result->value ()->content_type () == GDBMIValue::EMPTY_TYPE)); - GDBMITupleSafePtr gdbmi_tuple; - if (gdbmi_result->value ()->content_type () - != GDBMIValue::EMPTY_TYPE) { - gdbmi_tuple = gdbmi_result->value ()->get_tuple_content (); - THROW_IF_FAIL (gdbmi_tuple); + GDBMIListSafePtr gdbmi_list; + if (gdbmi_result->value ()->content_type () != GDBMIValue::EMPTY_TYPE) { + gdbmi_list = gdbmi_result->value ()->get_list_content (); + THROW_IF_FAIL (gdbmi_list); } - list result_list; - if (gdbmi_tuple) { - result_list = gdbmi_tuple->content (); - } - list::const_iterator it; - int thread_id=0; - for (it = result_list.begin (); it != result_list.end (); ++it) { - THROW_IF_FAIL (*it); - if ((*it)->variable () != "thread-id") { - LOG_ERROR ("expected a gdbmi value with " - "variable name 'thread-id'. " - "Got '" << (*it)->variable () << "'"); - return false; + if (gdbmi_list && !(gdbmi_list->empty ())) { + list value_list; + gdbmi_list->get_value_content (value_list); + + list::const_iterator value_iter; + for (value_iter = value_list.begin (); + value_iter != value_list.end (); + ++value_iter) { + THROW_IF_FAIL (*value_iter); + THROW_IF_FAIL ((*value_iter)->content_type () == GDBMIValue::TUPLE_TYPE); + GDBMITupleSafePtr gdbmi_tuple = (*value_iter)->get_tuple_content (); + list result_list = gdbmi_tuple->content (); + + int thread_id = 0; + string thread_name; + list::const_iterator it; + for (it = result_list.begin (); it != result_list.end (); ++it) { + + if ((*it)->variable () == "id") { + THROW_IF_FAIL ((*it)->value () + && ((*it)->value ()->content_type () + == GDBMIValue::STRING_TYPE)); + thread_id = atoi ((*it)->value ()->get_string_content ().c_str ()); + } else if((*it)->variable () == "target-id") { + // We don't use the target-id field for now + } else if((*it)->variable () == "name") { + THROW_IF_FAIL ((*it)->value () + && ((*it)->value ()->content_type () + == GDBMIValue::STRING_TYPE)); + thread_name = (*it)->value ()->get_string_content (); + } else if((*it)->variable () == "frame") { + // We don't use the frame field here because + // this information is retrived from another command + } else if((*it)->variable () == "state") { + // We don't use the state field for now + } else if((*it)->variable () == "core") { + // We don't use the core field for now + } else { + LOG_ERROR ("Got an unknown gbmi value which variable is '" + << gdbmi_result->variable () + << "'. Ignoring it thus."); + return false; + } + } + THROW_IF_FAIL (thread_id); + threads.push_back (make_pair(thread_id, thread_name)); } - THROW_IF_FAIL ((*it)->value () - && ((*it)->value ()->content_type () - == GDBMIValue::STRING_TYPE)); - thread_id = atoi ((*it)->value ()->get_string_content () - .c_str ()); - THROW_IF_FAIL (thread_id); - thread_ids.push_back (thread_id); } - } else if (gdbmi_result->variable () == "number-of-threads") { - // We've got a RESULT which variable is "number-of-threads", - // we expect the result to be a string which is the number - // of threads. - THROW_IF_FAIL (gdbmi_result->value () - && gdbmi_result->value ()->content_type () - == GDBMIValue::STRING_TYPE); - num_threads = - atoi (gdbmi_result->value ()->get_string_content ().c_str ()); } else if (gdbmi_result->variable () == "current-thread-id") { // If we've got a RESULT which variable is // "current-thread-id", expect the result to be a string @@ -2644,16 +2667,7 @@ GDBMIParser::parse_threads_list (UString::size_type a_from, SKIP_BLANK (cur); } - if (num_threads != thread_ids.size ()) { - LOG_ERROR ("num_threads: '" - << (int) num_threads - << "', thread_ids.size(): '" - << (int) thread_ids.size () - << "'"); - return false; - } - - a_thread_ids = thread_ids; + a_thread_ids = threads; a_to = cur; return true; } diff --git a/src/dbgengine/nmv-gdbmi-parser.h b/src/dbgengine/nmv-gdbmi-parser.h index aea914d..9943a9b 100644 --- a/src/dbgengine/nmv-gdbmi-parser.h +++ b/src/dbgengine/nmv-gdbmi-parser.h @@ -544,7 +544,7 @@ public: /// "-thread-list-ids". bool parse_threads_list (UString::size_type a_from, UString::size_type &a_to, - std::list &a_thread_ids); + std::list> &a_thread_ids); /// parses the result of the gdbmi command /// "-thread-select" diff --git a/src/dbgengine/nmv-i-debugger.h b/src/dbgengine/nmv-i-debugger.h index 63e2639..28fd1f6 100644 --- a/src/dbgengine/nmv-i-debugger.h +++ b/src/dbgengine/nmv-i-debugger.h @@ -31,6 +31,7 @@ #include #include #include +#include #include "common/nmv-api-macros.h" #include "common/nmv-ustring.h" #include "common/nmv-dynamic-module.h" @@ -59,6 +60,7 @@ using std::vector; using std::string; using std::map; using std::list; +using std::pair; NEMIVER_BEGIN_NAMESPACE (nemiver) @@ -1162,7 +1164,7 @@ public: const UString& /*cookie*/>& stopped_signal () const=0; virtual sigc::signal/*thread ids*/, + const list>/*thread ids and names*/, const UString& /*cookie*/>& threads_listed_signal () const =0; diff --git a/src/persp/dbgperspective/nmv-thread-list.cc b/src/persp/dbgperspective/nmv-thread-list.cc index ca38420..a6dbb88 100644 --- a/src/persp/dbgperspective/nmv-thread-list.cc +++ b/src/persp/dbgperspective/nmv-thread-list.cc @@ -35,10 +35,12 @@ NEMIVER_BEGIN_NAMESPACE (nemiver) struct ThreadListColumns : public Gtk::TreeModelColumnRecord { Gtk::TreeModelColumn thread_id; + Gtk::TreeModelColumn thread_name; ThreadListColumns () { add (thread_id); + add (thread_name); } };//end class ThreadListColumns @@ -109,7 +111,7 @@ struct ThreadList::Priv { NEMIVER_CATCH } - void on_debugger_threads_listed_signal (const std::list &a_threads, + void on_debugger_threads_listed_signal (const std::list> &a_threads, const UString &a_cookie) { LOG_FUNCTION_SCOPE_NORMAL_DD; @@ -183,6 +185,8 @@ struct ThreadList::Priv { tree_view->get_selection ()->set_mode (Gtk::SELECTION_SINGLE); tree_view->append_column (_("Thread ID"), thread_list_columns ().thread_id); + tree_view->append_column (_("Thread Name"), + thread_list_columns ().thread_name); Gtk::TreeViewColumn *column = tree_view->get_column (0); THROW_IF_FAIL (column); column->set_clickable (false); @@ -215,18 +219,19 @@ struct ThreadList::Priv { (sigc::mem_fun (*this, &Priv::on_draw_signal)); } - void set_a_thread_id (int a_id) + void set_a_thread_id (int a_id, const string &a_name) { THROW_IF_FAIL (list_store); Gtk::TreeModel::iterator iter = list_store->append (); iter->set_value (thread_list_columns ().thread_id, a_id); + iter->set_value (thread_list_columns ().thread_name, a_name); } - void set_thread_id_list (const std::list &a_list) + void set_thread_id_list (const std::list> &a_list) { - std::list::const_iterator it; + std::list>::const_iterator it; for (it = a_list.begin (); it != a_list.end (); ++it) { - set_a_thread_id (*it); + set_a_thread_id (it->first, it->second); } } -- 2.9.3