citrun

watch C/C++ source code execute
Log | Files | Refs | LICENSE

commit 05702f035e4f214664f202f3073dfdaad0d5d570
parent fe3fbb54115a20defe87f7066e3d53c02b0a46ad
Author: Kyle Milz <kyle@0x30.net>
Date:   Sun,  4 Dec 2016 17:13:49 -0700

src: replace logger with hand made stream buffer

Diffstat:
Msrc/Jamfile | 1-
Msrc/inst_action.cc | 12++++++------
Msrc/inst_frontend.cc | 31++++++++++++++++---------------
Dsrc/inst_log.cc | 46----------------------------------------------
Msrc/inst_log.h | 66++++++++++++++++++++++++++++++++++++++++--------------------------
Msrc/inst_main.cc | 14+++++++-------
Mt/inst_log.sh | 16++++++++--------
Mt/inst_preprocess.sh | 4++--
8 files changed, 79 insertions(+), 111 deletions(-)

diff --git a/src/Jamfile b/src/Jamfile @@ -56,7 +56,6 @@ Main citrun-gl : $(GL_SRCS) ; # citrun-inst # INST_SRCS = - inst_log.cc inst_main.cc inst_frontend.cc inst_action.cc diff --git a/src/inst_action.cc b/src/inst_action.cc @@ -43,20 +43,20 @@ InstrumentAction::write_modified_src(clang::FileID const &fid) if (m_is_citruninst) { out_file += ".citrun"; - *m_log << "Writing modified source to '" << out_file << "'.\n"; + *m_log << "Writing modified source to '" << out_file << "'" << std::endl; } std::error_code ec; llvm::raw_fd_ostream output(out_file, ec, llvm::sys::fs::F_None); if (ec.value()) { *m_log << "Error writing modified source '" << out_file - << "': " << ec.message() << "\n"; + << "': " << ec.message() << std::endl; return; } // Write the instrumented source file m_TheRewriter.getEditBuffer(fid).write(output); - *m_log << "Modified source written successfully.\n"; + *m_log << "Modified source written successfully." << std::endl; } void @@ -99,8 +99,8 @@ InstrumentAction::EndSourceFileAction() return; } - *m_log << "Instrumentation of '" << m_compiler_file_name << "' finished:\n"; - *m_log << " " << num_lines << " Lines of source code\n"; + *m_log << "Instrumentation of '" << m_compiler_file_name << "' finished:" << std::endl; + *m_log << " " << num_lines << " Lines of source code" << std::endl; // // Write out statistics from the AST visitor. @@ -110,7 +110,7 @@ InstrumentAction::EndSourceFileAction() if (v.m_counters[i] == 0) continue; *m_log << " " << v.m_counters[i] << " " - << v.m_counter_descr[i] << "\n"; + << v.m_counter_descr[i] << std::endl; } write_modified_src(main_fid); diff --git a/src/inst_frontend.cc b/src/inst_frontend.cc @@ -87,7 +87,7 @@ InstrumentFrontend::save_if_srcfile(char *arg) return; m_source_files.push_back(arg); - *m_log << "Found source file '" << arg << "'.\n"; + *m_log << "Found source file '" << arg << "'" << std::endl; if (m_is_citruninst) // In this mode the modified source file is written to a @@ -119,8 +119,9 @@ InstrumentFrontend::if_link_add_runtime(bool object_arg, bool compile_arg) if (!linking) return; + *m_log << "Link detected, adding '"<< CITRUN_SHARE "/libcitrun.a" + << "' to command line." << std::endl; m_args.push_back(const_cast<char *>(CITRUN_SHARE "/libcitrun.a")); - *m_log << "Link detected, adding '"<< m_args.back() << "' to command line.\n"; } void @@ -135,7 +136,7 @@ InstrumentFrontend::process_cmdline() if (std::strcmp(arg, "-E") == 0 || std::strcmp(arg, "-MM") == 0) { - *m_log << "Preprocessor argument found\n"; + *m_log << "Preprocessor argument found" << std::endl; exec_compiler(); } else if (std::strcmp(arg, "-o") == 0) @@ -145,13 +146,13 @@ InstrumentFrontend::process_cmdline() save_if_srcfile(arg); } - *m_log << "Command line is '" << cmd_line.str() << "'.\n"; + *m_log << "Command line is '" << cmd_line.str() << "'" << std::endl; if_link_add_runtime(object_arg, compile_arg); if (m_source_files.size() != 0) return; - *m_log << "No source files found on command line.\n"; + *m_log << "No source files found on command line." << std::endl; if (m_is_citruninst) exit(0); @@ -176,7 +177,7 @@ InstrumentFrontend::instrument() *m_log << "Added clangtool argument '" << clang_argv.back() << "'.\n"; #elif defined(__APPLE__) clang_argv.push_back("-I/opt/local/libexec/llvm-3.8/lib/clang/3.8.1/include"); - *m_log << "Added clangtool argument '" << clang_argv.back() << "'.\n"; + *m_log << "Added clangtool argument '" << clang_argv.back() << "'" << std::endl; #endif int clang_argc = clang_argv.size(); @@ -188,9 +189,9 @@ InstrumentFrontend::instrument() clang::DiagnosticOptions diags; clang::TextDiagnosticPrinter *log; - log = new clang::TextDiagnosticPrinter(m_log->m_outfile, &diags, false); - log->setPrefix(std::to_string(m_log->m_pid)); - Tool.setDiagnosticConsumer(log); + //log = new clang::TextDiagnosticPrinter(m_log, &diags, false); + // log->setPrefix(std::to_string(m_log->m_pid)); + //Tool.setDiagnosticConsumer(log); std::unique_ptr<InstrumentActionFactory> f = llvm::make_unique<InstrumentActionFactory>(m_log, m_is_citruninst, m_source_files); @@ -202,7 +203,7 @@ void InstrumentFrontend::restore_original_src() { for (auto &tmp_file : m_temp_file_map) { - *m_log << "Restored '" << tmp_file.first << "'.\n"; + *m_log << "Restored '" << tmp_file.first << "'" << std::endl; copy_file(tmp_file.first, tmp_file.second); unlink(tmp_file.second.c_str()); @@ -213,10 +214,10 @@ void InstrumentFrontend::exec_compiler() { // XXX: Need to destroy log here. - m_log->m_outfile.flush(); + // m_log->m_outfile.flush(); if (m_is_citruninst) { - *m_log << "Running as citrun-inst, not re-exec()'ing\n"; + *m_log << "Running as citrun-inst, not re-exec()'ing" << std::endl; exit(0); } @@ -229,7 +230,7 @@ int InstrumentFrontend::fork_compiler() { // Otherwise we'll get two copies of buffers after fork(). - m_log->m_outfile.flush(); + // m_log->m_outfile.flush(); pid_t child_pid; if ((child_pid = fork()) < 0) @@ -240,7 +241,7 @@ InstrumentFrontend::fork_compiler() exec_compiler(); *m_log << "Forked '" << m_args[0] << "' " - << "pid is '" << child_pid << "'.\n"; + << "pid is '" << child_pid << "'" << std::endl; int status; if (waitpid(child_pid, &status, 0) < 0) @@ -251,6 +252,6 @@ InstrumentFrontend::fork_compiler() if (WIFEXITED(status)) exit = WEXITSTATUS(status); - *m_log << "'" << child_pid << "' exited " << exit << ".\n"; + *m_log << "'" << child_pid << "' exited " << exit << "." << std::endl; return exit; } diff --git a/src/inst_log.cc b/src/inst_log.cc @@ -1,46 +0,0 @@ -#include "inst_log.h" - -#include <iostream> -#include <llvm/Support/FileSystem.h> // llvm::sys::fs::F_Append - -InstrumentLogger::InstrumentLogger(const bool &is_citruninst) : - m_iscitruninst(is_citruninst), - m_needs_prefix(true), - m_pid(getpid()), - m_ec(), - m_outfile("citrun.log", m_ec, llvm::sys::fs::F_Append) -{ - if (m_ec.value()) - std::cerr << "Can't open citrun.log: " << m_ec.message(); -} - -InstrumentLogger& -operator<<(InstrumentLogger& out, const char *rhs) -{ - if (out.m_ec.value()) - return out; - - out.print_prefix(); - out.m_outfile << rhs; - if (out.m_iscitruninst) - llvm::outs() << rhs; - out.check_newline(rhs); - - return out; -} - -void -InstrumentLogger::print_prefix() -{ - if (m_needs_prefix) { - m_outfile << m_pid << ": "; - m_needs_prefix = false; - } -} - -void -InstrumentLogger::check_newline(const std::string &rhs) -{ - if (std::find(rhs.begin(), rhs.end(), '\n') != rhs.end()) - m_needs_prefix = true; -} diff --git a/src/inst_log.h b/src/inst_log.h @@ -1,37 +1,51 @@ #ifndef _INST_LOG_H #define _INST_LOG_H +#include <iostream> #include <llvm/Support/raw_ostream.h> -#include <unistd.h> // pid_t - -class InstrumentLogger { -private: - void print_prefix(); - void check_newline(const std::string &); - - bool m_iscitruninst; - bool m_needs_prefix; +#include <llvm/Support/FileSystem.h> // llvm::sys::fs::F_Append +#include <sstream> +#include <unistd.h> // pid_t +class InstrumentLogger : public std::ostream +{ + class LogBuffer : public std::stringbuf + { + bool m_iscitruninst; + pid_t m_pid; + std::error_code m_ec; + llvm::raw_fd_ostream m_outfile; + public: + LogBuffer(const bool &is_citruninst) : + m_iscitruninst(is_citruninst), + m_pid(getpid()), + m_ec(), + m_outfile("citrun.log", m_ec, llvm::sys::fs::F_Append) + { + if (m_ec.value()) + std::cerr << "Can't open citrun.log: " << m_ec.message(); + } + + virtual int sync() + { + m_outfile << m_pid << ": " << str(); + + if (m_iscitruninst) + llvm::outs() << str(); + + str(""); + m_outfile.flush(); + return 0; + } + }; + + LogBuffer buffer; public: - InstrumentLogger(const bool &); - - template <typename T> - friend InstrumentLogger& operator<<(InstrumentLogger& out, const T &rhs) + InstrumentLogger(const bool &is_citruninst) : + std::ostream(&buffer), + buffer(is_citruninst) { - if (out.m_ec.value()) - return out; - - out.print_prefix(); - out.m_outfile << rhs; - if (out.m_iscitruninst) - llvm::outs() << rhs; - return out; } - friend InstrumentLogger& operator<<(InstrumentLogger&, const char *); - - pid_t m_pid; - std::error_code m_ec; - llvm::raw_fd_ostream m_outfile; }; #endif // _INST_LOG_H_ diff --git a/src/inst_main.cc b/src/inst_main.cc @@ -32,7 +32,7 @@ clean_PATH(InstrumentLogger &llog) if ((path = std::getenv("PATH")) == NULL) errx(1, "Error: PATH is not set."); - llog << "PATH='" << path << "'\n"; + llog << "PATH='" << path << "'" << std::endl; // Filter CITRUN_SHARE out of PATH std::stringstream path_ss(path); @@ -75,7 +75,7 @@ print_toolinfo(InstrumentLogger &llog) << utsname.release << " " << utsname.machine << ") "; } - llog << "'" << CITRUN_SHARE << "'\n"; + llog << "'" << CITRUN_SHARE << "'" << std::endl; } int @@ -96,7 +96,7 @@ main(int argc, char *argv[]) print_toolinfo(llog); if (is_citruninst) { - llog << ">> Welcome to C It Run! Have a nice day.\n"; + llog << ">> Welcome to C It Run! Have a nice day." << std::endl; } else { // There's extra work to do if we're not running as citrun-inst. llog << "Tool called as '" << argv[0] << "'"; @@ -104,7 +104,7 @@ main(int argc, char *argv[]) llog << ", changing to '" << base_name << "'"; argv[0] = base_name; } - llog << ".\n"; + llog << std::endl; setprogname("citrun-inst"); clean_PATH(llog); @@ -114,12 +114,12 @@ main(int argc, char *argv[]) main.process_cmdline(); int ret = main.instrument(); - llog << "Rewriting " << (ret ? "failed.\n" : "successful.\n"); + llog << "Rewriting " << (ret ? "failed." : "successful.") << std::endl; std::chrono::high_resolution_clock::time_point now = std::chrono::high_resolution_clock::now(); llog << std::chrono::duration_cast<std::chrono::milliseconds>(now - m_start_time).count() - << " Milliseconds spent rewriting source.\n"; + << " Milliseconds spent rewriting source." << std::endl; if (is_citruninst) return ret; @@ -132,7 +132,7 @@ main(int argc, char *argv[]) ret = main.fork_compiler(); llog << "Rewritten source compile " - << (ret ? "failed.\n" : "successful.\n"); + << (ret ? "failed." : "successful.") << std::endl; main.restore_original_src(); if (ret) diff --git a/t/inst_log.sh b/t/inst_log.sh @@ -41,11 +41,11 @@ strip_log citrun.log cat <<EOF > citrun.log.good citrun-inst 0.0 () '' -Tool called as ''. +Tool called as '' PATH='' -Found source file ''. -Command line is ''. -Added clangtool argument ''. +Found source file '' +Command line is '' +Added clangtool argument '' Instrumentation of '' finished: 22 Lines of source code 2 Function definitions @@ -56,14 +56,14 @@ Instrumentation of '' finished: 6 Binary operators Modified source written successfully. Rewriting successful. -Forked ''. +Forked '' '' exited 0. Rewritten source compile successful. -Restored ''. +Restored '' citrun-inst 0.0 () '' -Tool called as ''. +Tool called as '' PATH='' -Command line is ''. +Command line is '' Link detected, adding '' to command line. No source files found on command line. EOF diff --git a/t/inst_preprocess.sh b/t/inst_preprocess.sh @@ -16,11 +16,11 @@ ok "wrapping compile w/ preprocessor arg -MM" citrun-wrap cc -E prepro.c cat <<EOF > citrun.log.good citrun-inst 0.0 () '' -Tool called as ''. +Tool called as '' PATH='' Preprocessor argument found citrun-inst 0.0 () '' -Tool called as ''. +Tool called as '' PATH='' Preprocessor argument found EOF