feat(frontends/lean): add SHOW and SLEEP debugging support commands, fixes worker interrupted bug, and LEAN_SERVER_DIAGNOSTIC compilation mode
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
parent
c320c6e05a
commit
cb27407fcb
2 changed files with 47 additions and 2 deletions
|
@ -7,10 +7,19 @@ Author: Leonardo de Moura
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include "util/sstream.h"
|
#include "util/sstream.h"
|
||||||
|
#include "util/exception.h"
|
||||||
#include "util/sexpr/option_declarations.h"
|
#include "util/sexpr/option_declarations.h"
|
||||||
#include "frontends/lean/server.h"
|
#include "frontends/lean/server.h"
|
||||||
#include "frontends/lean/parser.h"
|
#include "frontends/lean/parser.h"
|
||||||
|
|
||||||
|
// #define LEAN_SERVER_DIAGNOSTIC
|
||||||
|
|
||||||
|
#if defined(LEAN_SERVER_DIAGNOSTIC)
|
||||||
|
#define DIAG(CODE) CODE
|
||||||
|
#else
|
||||||
|
#define DIAG(CODE)
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace lean {
|
namespace lean {
|
||||||
server::file::file(std::istream & in, std::string const & fname):m_fname(fname) {
|
server::file::file(std::istream & in, std::string const & fname):m_fname(fname) {
|
||||||
for (std::string line; std::getline(in, line);) {
|
for (std::string line; std::getline(in, line);) {
|
||||||
|
@ -59,6 +68,12 @@ void server::file::remove_line(unsigned linenum) {
|
||||||
m_lines.pop_back();
|
m_lines.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void server::file::show(std::ostream & out) {
|
||||||
|
lock_guard<mutex> lk(m_lines_mutex);
|
||||||
|
for (unsigned i = 0; i < m_lines.size(); i++)
|
||||||
|
out << m_lines[i] << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief Return index i <= m_snapshots.size() s.t.
|
\brief Return index i <= m_snapshots.size() s.t.
|
||||||
* forall j < i, m_snapshots[j].m_line < line
|
* forall j < i, m_snapshots[j].m_line < line
|
||||||
|
@ -119,8 +134,10 @@ server::worker::worker(environment const & env, io_state const & ios, definition
|
||||||
}
|
}
|
||||||
// extract block of code and snapshot from todo_file
|
// extract block of code and snapshot from todo_file
|
||||||
reset_interrupt();
|
reset_interrupt();
|
||||||
|
bool worker_interrupted = false;
|
||||||
if (m_terminate)
|
if (m_terminate)
|
||||||
break;
|
break;
|
||||||
|
DIAG(std::cerr << "processing '" << todo_file->get_fname() << "'\n";)
|
||||||
std::string block;
|
std::string block;
|
||||||
unsigned num_lines;
|
unsigned num_lines;
|
||||||
snapshot s;
|
snapshot s;
|
||||||
|
@ -139,8 +156,13 @@ server::worker::worker(environment const & env, io_state const & ios, definition
|
||||||
// parse block of code with respect to snapshot
|
// parse block of code with respect to snapshot
|
||||||
try {
|
try {
|
||||||
std::istringstream strm(block);
|
std::istringstream strm(block);
|
||||||
|
#if defined(LEAN_SERVER_DIAGNOSTIC)
|
||||||
|
std::shared_ptr<output_channel> out1(new stderr_channel());
|
||||||
|
std::shared_ptr<output_channel> out2(new stderr_channel());
|
||||||
|
#else
|
||||||
std::shared_ptr<output_channel> out1(new string_output_channel());
|
std::shared_ptr<output_channel> out1(new string_output_channel());
|
||||||
std::shared_ptr<output_channel> out2(new string_output_channel());
|
std::shared_ptr<output_channel> out2(new string_output_channel());
|
||||||
|
#endif
|
||||||
io_state tmp_ios(_ios, out1, out2);
|
io_state tmp_ios(_ios, out1, out2);
|
||||||
tmp_ios.set_options(join(s.m_options, _ios.get_options()));
|
tmp_ios.set_options(join(s.m_options, _ios.get_options()));
|
||||||
bool use_exceptions = false;
|
bool use_exceptions = false;
|
||||||
|
@ -149,8 +171,13 @@ server::worker::worker(environment const & env, io_state const & ios, definition
|
||||||
s.m_lds, s.m_eds, s.m_line, &todo_file->m_snapshots, &todo_file->m_info);
|
s.m_lds, s.m_eds, s.m_line, &todo_file->m_snapshots, &todo_file->m_info);
|
||||||
p.set_cache(&m_cache);
|
p.set_cache(&m_cache);
|
||||||
p();
|
p();
|
||||||
} catch (exception&) {}
|
} catch (interrupted &) {
|
||||||
if (!m_terminate) {
|
worker_interrupted = true;
|
||||||
|
} catch (exception & ex) {
|
||||||
|
DIAG(std::cerr << "worker exception: " << ex.what() << "\n";)
|
||||||
|
}
|
||||||
|
if (!m_terminate && !worker_interrupted) {
|
||||||
|
DIAG(std::cerr << "finished '" << todo_file->get_fname() << "'\n";)
|
||||||
unique_lock<mutex> lk(m_todo_mutex);
|
unique_lock<mutex> lk(m_todo_mutex);
|
||||||
if (m_todo_file == todo_file && m_last_file == todo_file && m_todo_linenum == todo_linenum) {
|
if (m_todo_file == todo_file && m_last_file == todo_file && m_todo_linenum == todo_linenum) {
|
||||||
m_todo_linenum = num_lines + 1;
|
m_todo_linenum = num_lines + 1;
|
||||||
|
@ -216,6 +243,8 @@ static std::string g_wait("WAIT");
|
||||||
static std::string g_clear_cache("CLEAR_CACHE");
|
static std::string g_clear_cache("CLEAR_CACHE");
|
||||||
static std::string g_echo("ECHO");
|
static std::string g_echo("ECHO");
|
||||||
static std::string g_options("OPTIONS");
|
static std::string g_options("OPTIONS");
|
||||||
|
static std::string g_show("SHOW");
|
||||||
|
static std::string g_sleep("SLEEP");
|
||||||
|
|
||||||
static bool is_command(std::string const & cmd, std::string const & line) {
|
static bool is_command(std::string const & cmd, std::string const & line) {
|
||||||
return line.compare(0, cmd.size(), cmd) == 0;
|
return line.compare(0, cmd.size(), cmd) == 0;
|
||||||
|
@ -358,6 +387,13 @@ void server::show_options() {
|
||||||
m_out << "-- ENDOPTIONS" << std::endl;
|
m_out << "-- ENDOPTIONS" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void server::show() {
|
||||||
|
check_file();
|
||||||
|
m_out << "-- BEGINSHOW" << std::endl;
|
||||||
|
m_file->show(m_out);
|
||||||
|
m_out << "-- ENDSHOW" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
bool server::operator()(std::istream & in) {
|
bool server::operator()(std::istream & in) {
|
||||||
for (std::string line; std::getline(in, line);) {
|
for (std::string line; std::getline(in, line);) {
|
||||||
try {
|
try {
|
||||||
|
@ -398,6 +434,12 @@ bool server::operator()(std::istream & in) {
|
||||||
show_options();
|
show_options();
|
||||||
} else if (is_command(g_wait, line)) {
|
} else if (is_command(g_wait, line)) {
|
||||||
m_worker.wait();
|
m_worker.wait();
|
||||||
|
} else if (is_command(g_show, line)) {
|
||||||
|
show();
|
||||||
|
} else if (is_command(g_sleep, line)) {
|
||||||
|
unsigned ms = get_linenum(line, g_sleep);
|
||||||
|
chrono::milliseconds d(ms);
|
||||||
|
this_thread::sleep_for(d);
|
||||||
} else {
|
} else {
|
||||||
throw exception(sstream() << "unexpected command line: " << line);
|
throw exception(sstream() << "unexpected command line: " << line);
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,8 @@ class server {
|
||||||
void replace_line(unsigned linenum, std::string const & new_line);
|
void replace_line(unsigned linenum, std::string const & new_line);
|
||||||
void insert_line(unsigned linenum, std::string const & new_line);
|
void insert_line(unsigned linenum, std::string const & new_line);
|
||||||
void remove_line(unsigned linenum);
|
void remove_line(unsigned linenum);
|
||||||
|
void show(std::ostream & out);
|
||||||
|
std::string const & get_fname() const { return m_fname; }
|
||||||
info_manager const & infom() const { return m_info; }
|
info_manager const & infom() const { return m_info; }
|
||||||
};
|
};
|
||||||
typedef std::shared_ptr<file> file_ptr;
|
typedef std::shared_ptr<file> file_ptr;
|
||||||
|
@ -84,6 +86,7 @@ class server {
|
||||||
void read_line(std::istream & in, std::string & line);
|
void read_line(std::istream & in, std::string & line);
|
||||||
void interrupt_worker();
|
void interrupt_worker();
|
||||||
void show_options();
|
void show_options();
|
||||||
|
void show();
|
||||||
unsigned get_linenum(std::string const & line, std::string const & cmd);
|
unsigned get_linenum(std::string const & line, std::string const & cmd);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
Loading…
Reference in a new issue