[nemiver/follow-fork-mode: 10/35] Support original-location attr on pending breakpoints.
- From: Dodji Seketeli <dodji src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [nemiver/follow-fork-mode: 10/35] Support original-location attr on pending breakpoints.
- Date: Thu, 6 May 2010 10:16:56 +0000 (UTC)
commit 0f8719286729a54103bce86e514d3a3bce62d0b5
Author: Dodji Seketeli <dodji redhat com>
Date: Sat Apr 10 12:48:28 2010 +0200
Support original-location attr on pending breakpoints.
* src/common/nmv-str-utils.h (extract_path_and_line_num_from_location):
Remove use of UString in the declaration.
(chomp): Turn this into a template.
* src/common/nmv-str-utils.cc (extract_path_and_line_num_from_location):
Adjust and make it much more robust.
* src/dbgengine/nmv-gdbmi-parser.cc (GDBMIParser::parse_breakpoint):
Adjust to recent (GDB 7?) behaviour wrt PENDING breakpoints.
Now, the original location is in the original-location
attribute.
src/common/nmv-str-utils.cc | 57 +++++++++++++++++++----
src/common/nmv-str-utils.h | 34 ++++++++++++--
src/dbgengine/nmv-gdbmi-parser.cc | 89 +++++++++----------------------------
tests/test-gdbmi.cc | 8 +++
4 files changed, 105 insertions(+), 83 deletions(-)
---
diff --git a/src/common/nmv-str-utils.cc b/src/common/nmv-str-utils.cc
index 4b91c67..f814b87 100644
--- a/src/common/nmv-str-utils.cc
+++ b/src/common/nmv-str-utils.cc
@@ -33,18 +33,55 @@ NEMIVER_BEGIN_NAMESPACE (str_utils)
using nemiver::common::UString;
using namespace nemiver::common;
+// Return true if a_str is a location string of the form
+// "filename:number", where number is string of digits.
+// Keep in mind that filename can also be a path that contains ':'
+// itself. So this function tries hard to make sure what follows the ':'
+// is a real number and ends the string.
bool
-extract_path_and_line_num_from_location (const UString &a_location,
- UString &a_file_path,
- unsigned &a_line_num)
+extract_path_and_line_num_from_location (const std::string &a_str,
+ std::string &a_filename,
+ std::string &a_line_num)
{
- vector<UString> strs = a_location.split (":");
- if (strs.empty ())
- return false;
- a_file_path = strs[0];
- if (strs.size () > 1 && !strs[1].empty ())
- a_line_num = std::atoi (strs[1].c_str ());
- return true;
+ std::string filename;
+ std::string::size_type colon_pos;
+ bool result = false;
+ if ((colon_pos = a_str.find_last_of (":"))
+ == std::string::npos) {
+ // The string has no ':' character. Let's bail out.
+ } else {
+ // Is what comes after the comma a legit number?
+ bool is_number = true;
+ std::string::size_type str_len = colon_pos;
+
+ if (colon_pos + 1 >= a_str.length ())
+ is_number = false;
+ // Loop to make sure the thing after the ':' is an actual
+ // number.
+ std::string::size_type i;
+ for (i = colon_pos + 1; i < a_str.length (); ++i) {
+ if (!isdigit (a_str[i])) {
+ is_number = false;
+ break;
+ }
+ }
+ bool number_is_at_end_of_str = (i >= a_str.length ());
+
+ if (is_number && number_is_at_end_of_str) {
+ string file_name, line_num;
+
+ for (string::size_type i = 0; i < str_len; ++i)
+ a_filename.push_back (a_str[i]);
+
+ for (string::size_type i = colon_pos + 1; i < a_str.length (); ++i)
+ a_line_num.push_back (a_str[i]);
+ result = true;
+ } else {
+ // Bail out because the ':' is either not a legit number or
+ // not at the end of the string.
+ }
+ }
+ return result;
}
size_t
diff --git a/src/common/nmv-str-utils.h b/src/common/nmv-str-utils.h
index 68d45a4..b901902 100644
--- a/src/common/nmv-str-utils.h
+++ b/src/common/nmv-str-utils.h
@@ -32,10 +32,9 @@ NEMIVER_BEGIN_NAMESPACE (str_utils)
using nemiver::common::UString;
bool
-extract_path_and_line_num_from_location (const UString &a_location,
- UString &a_file_path,
- unsigned &a_line_num);
-
+extract_path_and_line_num_from_location (const std::string &a_location,
+ std::string &a_file_path,
+ std::string &a_line_num);
size_t hexa_to_int (const string &a_hexa_str);
std::string int_to_string (size_t an_int);
vector<UString> split (const UString &a_string, const UString &a_delim);
@@ -45,7 +44,32 @@ UString join (const vector<UString> &a_elements,
UString join (vector<UString>::const_iterator &a_from,
vector<UString>::const_iterator &a_to,
const UString &a_delim=" ");
-void chomp (UString &a_string);
+
+template<typename S>
+void
+chomp (S &a_string)
+{
+ if (!a_string.size ()) {return;}
+
+ Glib::ustring::size_type i = 0;
+
+ // remove the ws from the beginning of the string.
+ while (!a_string.empty () && isspace (a_string.at (0))) {
+ a_string.erase (0, 1);
+ }
+
+ // remove the ws from the end of the string.
+ i = a_string.size ();
+ if (!i) {return;}
+ --i;
+ while (i > 0 && isspace (a_string.at (i))) {
+ a_string.erase (i, 1);
+ i = a_string.size ();
+ if (!i) {return;}
+ --i;
+ }
+ if (i == 0 && isspace (a_string.at (i))) {a_string.erase (0, 1);}
+}
UString::size_type get_number_of_lines (const UString &a_string);
diff --git a/src/dbgengine/nmv-gdbmi-parser.cc b/src/dbgengine/nmv-gdbmi-parser.cc
index a9f2efa..09379eb 100644
--- a/src/dbgengine/nmv-gdbmi-parser.cc
+++ b/src/dbgengine/nmv-gdbmi-parser.cc
@@ -2089,15 +2089,14 @@ GDBMIParser::parse_breakpoint (Glib::ustring::size_type a_from,
}
++cur;
- if (attrs["addr"] == "<PENDING>") {
- UString pending = attrs["pending"];
- if (pending == "") {
- LOG_PARSING_ERROR2 (cur);
- return false;
- }
+ UString pending = attrs["pending"];
+ if (pending.empty ())
+ pending = attrs["original-location"];
+ if (!pending.empty ()) {
LOG_D ("got pending breakpoint: '" << pending << "'",
GDBMI_OUTPUT_DOMAIN);
- vector<UString> str_tab;
+ bool is_file_location = false;
+ string filename, line_num;
// pending contains either the name of the function the breakpoint
// has been set on, or the filename:linenumber location of the
// breakpoint.
@@ -2108,59 +2107,15 @@ GDBMIParser::parse_breakpoint (Glib::ustring::size_type a_from,
// Bear in mind that ':' can also be part of the path name. So we
// really need to detect if the last ':' is the separator betwen
// path and line number.
- std::string::size_type colon_pos;
- if ((colon_pos = pending.raw ().find_last_of (":"))
- == std::string::npos) {
- str_tab.push_back (pending);
- } else {
- // Is what comes after the comma a legit number?
- bool is_number = true;
- std::string::size_type str_len = colon_pos;
-
- if (colon_pos + 1 >= pending.raw ().length ())
- is_number = false;
- // Loop to make sure the thing after the ':' is an actual
- // number.
- std::string::size_type i;
- for (i = colon_pos + 1;
- i < pending.raw ().length ();
- ++i) {
- if (!isdigit (pending.raw ()[i])) {
- is_number = false;
- break;
- }
- }
- bool number_is_at_end_of_pending = (i >= pending.raw ().length ());
-
- if (is_number && number_is_at_end_of_pending) {
- string file_name, line_num;
-
- for (string::size_type i = 0; i < str_len; ++i)
- file_name.push_back (pending.raw ()[i]);
-
- for (string::size_type i = colon_pos + 1;
- i < pending.raw ().length ();
- ++i)
- line_num.push_back (pending.raw ()[i]);
-
- str_tab.push_back (file_name);
- str_tab.push_back (line_num);
- } else {
- str_tab.push_back (pending);
- }
- }
-
- // from now on, if str_tab.size () == 2 then it contains
- // the filename and line number of the breakpoint.
- // if it str_tab.size () == 1 then it contains the function name
- // the breakpoint was set on.
- // Otherwise an error occured
- if (str_tab.size () > 1) {
- LOG_D ("filepath: '" << str_tab[0] << "'", GDBMI_OUTPUT_DOMAIN);
- LOG_D ("linenum: '" << str_tab[1] << "'", GDBMI_OUTPUT_DOMAIN);
- }
- if (str_tab.size () == 2) {
- string path = Glib::locale_from_utf8 (str_tab[0]);
+ is_file_location =
+ str_utils::extract_path_and_line_num_from_location (pending.raw (),
+ filename,
+ line_num);
+
+ if (is_file_location) {
+ LOG_D ("filepath: '" << filename << "'", GDBMI_OUTPUT_DOMAIN);
+ LOG_D ("linenum: '" << line_num << "'", GDBMI_OUTPUT_DOMAIN);
+ string path = Glib::locale_from_utf8 (filename);
if (Glib::path_is_absolute (path)) {
attrs["file"] = Glib::locale_to_utf8
(Glib::path_get_basename (path));
@@ -2168,12 +2123,9 @@ GDBMIParser::parse_breakpoint (Glib::ustring::size_type a_from,
} else {
attrs["file"] = Glib::locale_to_utf8 (path);;
}
- attrs["line"] = str_tab[1];
- } else if (str_tab.size () == 1) {
- attrs["func"] = str_tab[0];
+ attrs["line"] = line_num;
} else {
- LOG_PARSING_ERROR2 (cur);
- return false;
+ attrs["func"] = pending;
}
}
@@ -2218,14 +2170,15 @@ GDBMIParser::parse_breakpoint (Glib::ustring::size_type a_from,
&& a_bkpt.file_name ().empty ()
&& (iter = attrs.find ("original-location")) != null_iter) {
UString location = iter->second;
- UString file_path;
- unsigned line_num = 0;
+ string file_path;
+ string line_num_str;
str_utils::extract_path_and_line_num_from_location (location,
file_path,
- line_num);
+ line_num_str);
// Line number must be present otherwise, that means
// what was encoded in the "original-location" RESULT wasn't
// "filepath:line-number"
+ unsigned line_num = atoi (line_num_str.c_str ());
if (!file_path.empty () && line_num) {
a_bkpt.file_full_name (file_path);
a_bkpt.line (line_num);
diff --git a/tests/test-gdbmi.cc b/tests/test-gdbmi.cc
index a9d738f..db503f4 100644
--- a/tests/test-gdbmi.cc
+++ b/tests/test-gdbmi.cc
@@ -150,6 +150,9 @@ static const char* gv_breakpoint_table3 =
static const char* gv_breakpoint_table4 =
"BreakpointTable={nr_rows=\"2\",nr_cols=\"6\",hdr=[{width=\"7\",alignment=\"-1\",col_name=\"number\",colhdr=\"Num\"},{width=\"14\",alignment=\"-1\",col_name=\"type\",colhdr=\"Type\"},{width=\"4\",alignment=\"-1\",col_name=\"disp\",colhdr=\"Disp\"},{width=\"3\",alignment=\"-1\",col_name=\"enabled\",colhdr=\"Enb\"},{width=\"18\",alignment=\"-1\",col_name=\"addr\",colhdr=\"Address\"},{width=\"40\",alignment=\"2\",col_name=\"what\",colhdr=\"What\"}],body=[bkpt={number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"0x000000000040aca0\",func=\"main\",file=\"main.cpp\",fullname=\"/home/philip/nemiver:temp/main.cpp\",line=\"77\",times=\"1\",original-location=\"main\"},bkpt={number=\"2\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"<PENDING>\",pending=\"/home/philip/nemiver:temp/main.cpp:78\",times=\"0\",original-location=\"/home/philip/nemiver:temp/main.cpp:78\"}]}";
+static const char* gv_breakpoint_table5 =
+"BreakpointTable={nr_rows=\"2\",nr_cols=\"6\",hdr=[{width=\"7\",alignment=\"-1\",col_name=\"number\",colhdr=\"Num\"},{width=\"14\",alignment=\"-1\",col_name=\"type\",colhdr=\"Type\"},{width=\"4\",alignment=\"-1\",col_name=\"disp\",colhdr=\"Disp\"},{width=\"3\",alignment=\"-1\",col_name=\"enabled\",colhdr=\"Enb\"},{width=\"18\",alignment=\"-1\",col_name=\"addr\",colhdr=\"Address\"},{width=\"40\",alignment=\"2\",col_name=\"what\",colhdr=\"What\"}],body=[bkpt={number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"0x000000000040cb85\",func=\"main(int, char**)\",file=\"main.cc\",fullname=\"/home/dodji/devel/git/nemiver-branches.git/asm-support/src/main.cc\",line=\"489\",times=\"1\",original-location=\"main\"},bkpt={number=\"3\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"<PENDING>\",file=\"nmv-dbg-perspective.cc\",line=\"4143\",times=\"0\",original-location=\"/home/dodji/devel/git/nemiver-branches.git/asm-support/src/persp/dbgperspective/nmv-dbg-perspecti
ve.cc:4143\"}]}";
+
static const char* gv_breakpoint0 =
"bkpt={number=\"2\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"<MULTIPLE>\",times=\"0\",original-location=\"/home/dodji/devel/srcs/test.cc:36\"}";
@@ -818,6 +821,11 @@ test_breakpoint_table ()
BOOST_REQUIRE_EQUAL (breakpoints[2].file_full_name (),
"/home/philip/nemiver:temp/main.cpp");
BOOST_REQUIRE_EQUAL (breakpoints[2].line (), 78);
+
+ cur = 0, cur = 0, breakpoints.clear ();
+ parser.push_input (gv_breakpoint_table5);
+ parser.set_mode (GDBMIParser::BROKEN_MODE);
+ BOOST_REQUIRE (parser.parse_breakpoint_table (cur, cur, breakpoints));
}
void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]