From 1b1b4cebda9ceaa7a2a2b695a32ecb2588045076 Mon Sep 17 00:00:00 2001 From: Rajan Arora Date: Thu, 9 Oct 2008 19:58:30 -0400 Subject: [PATCH] Display source context for error and warning messages (6701) --- ChangeLog | 24 +++++++++++++++ elaborate.cxx | 43 +++++++++++++++++++++++++++ parse.cxx | 30 +++++++++++++++++-- parse.h | 10 +++++-- session.h | 1 + staptree.h | 4 ++- tapsets.cxx | 2 +- testsuite/ChangeLog | 5 ++++ testsuite/parseko/source_context.stp | 5 ++++ testsuite/systemtap.base/warnings.exp | 2 ++ 10 files changed, 118 insertions(+), 8 deletions(-) create mode 100755 testsuite/parseko/source_context.stp diff --git a/ChangeLog b/ChangeLog index 8b1645e44..3806b475a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,27 @@ +2008-10-09 Rajan Arora + + * elaborate.cxx (systemtap_session::print_error_source): New. + (systemtap_session::print_error): Call it. + (systemtap_session::print_warning): Likewise. + * parse.cxx (parser::print_error): Likewise. + * session.h (struct systemtap_session::print_error_source): + Declare it. + * parse.cxx (lexer::get_input_contents): New. + (parser::parse): Call it. + (lexer::set_current_file): New. + (parser::parse): Call it. + * parse.h (class lexer::get_input_contents): Declare it. + (class lexer::set_current_file): Declare it. + (class lexer): New member current_file. + (class lexer): Update input_contents from vector + to std::string. + (struct source_loc): New member stap_file. + * staptree.h (struct stapfile): New member file_contents. + +2008-10-09 Stan Cox + + * tapsets.cxx (query_cu): Fix typo. + 2008-10-06 Wenji Huang PR 4886 diff --git a/elaborate.cxx b/elaborate.cxx index afdc796ea..9f0a2a746 100644 --- a/elaborate.cxx +++ b/elaborate.cxx @@ -1426,6 +1426,7 @@ void systemtap_session::print_error (const semantic_error& e) { string message_str[2]; + string align_semantic_error (" "); // NB: we don't print error messages during listing mode. if (listing_mode) return; @@ -1462,22 +1463,64 @@ systemtap_session::print_error (const semantic_error& e) { seen_errors.insert (message_str[1]); cerr << message_str[0]; + + if (e.tok1) + print_error_source (cerr, align_semantic_error, e.tok1); + + if (e.tok2) + print_error_source (cerr, align_semantic_error, e.tok2); } if (e.chain) print_error (* e.chain); } +void +systemtap_session::print_error_source (std::ostream& message, + std::string& align, const token* tok) +{ + unsigned i = 0; + unsigned line = tok->location.line; + unsigned col = tok->location.column; + string file_contents; + if (tok->location.stap_file) + file_contents = tok->location.stap_file->file_contents; + else + //No source to print, silently exit + return; + size_t start_pos = 0, end_pos = 0; + //Navigate to the appropriate line + while (i != line && end_pos != std::string::npos) + { + start_pos = end_pos; + end_pos = file_contents.find ('\n', start_pos) + 1; + i++; + } + message << align << "source: " << file_contents.substr (start_pos, end_pos-start_pos-1) << endl; + message << align << " "; + //Navigate to the appropriate column + for (i=start_pos; ilocation.file = input_name; + if (current_file) + n->location.stap_file = current_file; unsigned semiskipped_p = 0; @@ -945,6 +964,8 @@ stapfile* parser::parse () { stapfile* f = new stapfile; + input.set_current_file (f); + f->file_contents = input.get_input_contents (); f->name = input_name; bool empty = true; @@ -1013,15 +1034,18 @@ parser::parse () { cerr << "Input file '" << input_name << "' is empty or missing." << endl; delete f; + input.set_current_file (0); return 0; } else if (num_errors > 0) { cerr << num_errors << " parse error(s)." << endl; delete f; + input.set_current_file (0); return 0; } + input.set_current_file (0); return f; } diff --git a/parse.h b/parse.h index cf31f4f89..2e2b656f0 100644 --- a/parse.h +++ b/parse.h @@ -18,11 +18,14 @@ #include #include +struct stapfile; + struct source_loc { std::string file; unsigned line; unsigned column; + stapfile* stap_file; }; std::ostream& operator << (std::ostream& o, const source_loc& loc); @@ -71,6 +74,8 @@ class lexer public: token* scan (bool wildcard=false); lexer (std::istream&, const std::string&, systemtap_session&); + std::string get_input_contents (); + void set_current_file (stapfile* f); private: int input_get (); @@ -79,16 +84,15 @@ private: int input_peek (unsigned n=0); std::istream& input; std::string input_name; - std::vector input_contents; + std::string input_contents; int input_pointer; // index into input_contents unsigned cursor_suspend_count; unsigned cursor_line; unsigned cursor_column; systemtap_session& session; + stapfile* current_file; }; - -struct stapfile; struct probe; struct probe_alias; struct vardecl; diff --git a/session.h b/session.h index b8bd971a7..4746422f5 100644 --- a/session.h +++ b/session.h @@ -179,6 +179,7 @@ struct systemtap_session const token* last_token; void print_token (std::ostream& o, const token* tok); void print_error (const semantic_error& e); + void print_error_source (std::ostream&, std::string&, const token* tok); void print_warning (const std::string& w, const token* tok = 0); // reNB: new POD members likely need to be explicitly cleared in the ctor. diff --git a/staptree.h b/staptree.h index 770a731e0..c35728cbf 100644 --- a/staptree.h +++ b/staptree.h @@ -574,8 +574,10 @@ struct stapfile std::vector functions; std::vector globals; std::vector embeds; + std::string file_contents; bool privileged; - stapfile (): privileged (false) {} + stapfile (): file_contents (""), + privileged (false) {} void print (std::ostream& o) const; }; diff --git a/tapsets.cxx b/tapsets.cxx index a5a62c7ae..3a70936f5 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -3799,7 +3799,7 @@ query_cu (Dwarf_Die * cudie, void * arg) { stringstream msg; msg << "address 0x" << hex << queryaddr - << "does not match the begining of a statement"; + << " does not match the beginning of a statement"; throw semantic_error(msg.str()); } } diff --git a/testsuite/ChangeLog b/testsuite/ChangeLog index 5ddee32c3..ceef8c40d 100644 --- a/testsuite/ChangeLog +++ b/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2008-10-09 Rajan Arora + + * systemtap.base/warnings.exp: Allow for source: lines. + * parseko/source_context.stp: New file. + 2008-10-04 Mark Wielaard * systemtap.base/debugpath.exp: Guess a bit more intelligently diff --git a/testsuite/parseko/source_context.stp b/testsuite/parseko/source_context.stp new file mode 100755 index 000000000..403b203b7 --- /dev/null +++ b/testsuite/parseko/source_context.stp @@ -0,0 +1,5 @@ +probe timer.ms(123) +{ +printf("Probe successful\n") + eeexit () +} diff --git a/testsuite/systemtap.base/warnings.exp b/testsuite/systemtap.base/warnings.exp index a90860d97..4bbef40d0 100644 --- a/testsuite/systemtap.base/warnings.exp +++ b/testsuite/systemtap.base/warnings.exp @@ -6,6 +6,8 @@ expect { -timeout 30 -re {^WARNING:[^\r\n]*\r\n} { incr ok; exp_continue } -re {^[^\r\n]*.ko\r\n} { incr ok; exp_continue } + -re {^[^\r]*source:[^\r\n]*\r\n} {exp_continue} + -re {^[^\r\n]*\^[^\r\n]*\r\n} {exp_continue} timeout { fail "$test (timeout)" } eof { } } -- 2.43.5