citrun

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

commit c3f75ad9f2348f36846fdf1c3e2939599ec343e2
parent ef7d1fccdd5ebca036aed2c4074d237e22841450
Author: Kyle Milz <kyle@0x30.net>
Date:   Sun,  7 Aug 2016 20:18:13 -0600

src: allow citrun-inst to be ran directly

- in this mode, write the modified source code to an alternate file

Diffstat:
Msrc/inst_action.cc | 11+++++++++--
Msrc/inst_main.cc | 30+++++++++++++++++++++---------
2 files changed, 30 insertions(+), 11 deletions(-)

diff --git a/src/inst_action.cc b/src/inst_action.cc @@ -70,7 +70,7 @@ InstrumentAction::EndSourceFileAction() std::string header = ss.str(); unsigned header_sz = std::count(header.begin(), header.end(), '\n'); - if (m_TheRewriter.InsertTextAfter(start, header)) { + if (!m_is_citruninst && m_TheRewriter.InsertTextAfter(start, header)) { *m_log << m_pfx << "Failed inserting " << header_sz << " lines of instrumentation preabmle."; return; @@ -90,8 +90,15 @@ InstrumentAction::EndSourceFileAction() *m_log << m_pfx << " " << v.m_callexpr << " Call expressions\n"; *m_log << m_pfx << " " << v.m_totalstmt << " Total statements in source\n"; + std::string out_file(file_name); + if (m_is_citruninst) { + out_file = file_name + ".citrun"; + *m_log << m_pfx << "Writing modified source to '" + << out_file << "'.\n"; + } + std::error_code ec; - llvm::raw_fd_ostream output(file_name, ec, llvm::sys::fs::F_None); + llvm::raw_fd_ostream output(out_file, ec, llvm::sys::fs::F_None); if (ec.value()) { *m_log << m_pfx << "Error writing modified source: " << ec.message() << "\n"; diff --git a/src/inst_main.cc b/src/inst_main.cc @@ -85,10 +85,8 @@ CitrunInst::CitrunInst(int argc, char *argv[]) : m_args[0] = base_name; } - if (std::strcmp(m_args[0], "citrun-inst") == 0) { - m_log << m_pfx << "citrun-inst called directly.\n"; + if (std::strcmp(m_args[0], "citrun-inst") == 0) m_is_citruninst = true; - } setprogname("citrun-inst"); } @@ -96,8 +94,11 @@ CitrunInst::CitrunInst(int argc, char *argv[]) : void CitrunInst::clean_PATH() { - char *path; + if (m_is_citruninst) + // Running citrun-inst directly is guarded against exec() loops + return; + char *path; if ((path = std::getenv("PATH")) == NULL) { m_log << m_pfx << "PATH is not set.\n"; errx(1, "PATH must be set"); @@ -185,6 +186,11 @@ CitrunInst::save_if_srcfile(char *arg) m_source_files.push_back(arg); m_log << m_pfx << "Found source file '" << arg << "'.\n"; + if (m_is_citruninst) + // In this mode the modified source file is written to a + // completely different file. + return; + char *dst_fn; if ((dst_fn = std::tmpnam(NULL)) == NULL) err(1, "tmpnam"); @@ -289,13 +295,19 @@ CitrunInst::instrument() Tool.setDiagnosticConsumer(log); std::unique_ptr<InstrumentActionFactory> f = - llvm::make_unique<InstrumentActionFactory>(&m_log, m_pfx, false); - if (Tool.run(f.get())) { - m_log << m_pfx << "Instrumentation failed.\n"; - return try_unmodified_compile(); + llvm::make_unique<InstrumentActionFactory>(&m_log, m_pfx, m_is_citruninst); + + int ret = Tool.run(f.get()); + m_log << m_pfx << "Instrumentation " << (ret ? "failed.\n" : "successful.\n"); + + if (m_is_citruninst) { + // Nothing left to do if we're in this mode. + m_log.close(); + exit(ret); } - m_log << m_pfx << "Instrumentation successful.\n"; + if (ret) + return try_unmodified_compile(); return 0; }