citrun

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

commit bd4f2ed2015c10f06eac77434383d22273da7b06
parent 5239579cfbea9adddf1b4e2630726bbc320da240
Author: kyle <kyle@getaddrinfo.net>
Date:   Sat,  5 Mar 2016 17:53:25 -0700

instrument: add smarts to link object files together

- use a linked list of global structures to access all coverage vectors
  - this should allow lock free reading of all values

Diffstat:
Minstrument/instrumenter.cpp | 77+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 71 insertions(+), 6 deletions(-)

diff --git a/instrument/instrumenter.cpp b/instrument/instrumenter.cpp @@ -1,10 +1,13 @@ #include <err.h> #include <fcntl.h> // open +#include <limits.h> #include <sys/stat.h> // mode flags +#include <unistd.h> // getcwd, access +#include <fstream> +#include <iostream> #include <sstream> #include <string> -#include <iostream> #include <clang/AST/AST.h> #include <clang/Lex/Lexer.h> @@ -75,8 +78,8 @@ instrumenter::VisitFunctionDecl(FunctionDecl *f) { // Only function definitions (with bodies), not declarations. if (f->hasBody()) { - Stmt *FuncBody = f->getBody(); #if 0 + Stmt *FuncBody = f->getBody(); // Type name as string QualType QT = f->getReturnType(); std::string TypeStr = QT.getAsString(); @@ -122,6 +125,49 @@ MyFrontendAction::CreateASTConsumer(CompilerInstance &CI, StringRef file) return new MyASTConsumer(TheRewriter); } +unsigned int +get_src_number() +{ + char *cwd = getcwd(NULL, PATH_MAX); + if (cwd == NULL) + errx(1, "getcwd"); + std::string src_number_filename(cwd); + src_number_filename.append("/SRC_NUMBER"); + + std::cerr << "src num file is " << src_number_filename << std::endl; + + std::fstream src_number_file; + + if (access(src_number_filename.c_str(), F_OK) == -1) { + // SRC_NUMBER does not exist + std::cerr << "SRC_NUMBER does not exist" << std::endl; + std::cerr << "creating with contents '0'" << std::endl; + + // Create SRC_NUMBER + src_number_file.open(src_number_filename, std::fstream::out); + src_number_file << 0; + src_number_file.close(); + + // First source file is zero + return 0; + } + + // SRC_NUMBER existed, read its contents and write incremented value + src_number_file.open(src_number_filename, std::fstream::in | std::fstream::out); + + unsigned int src_num = 0; + src_number_file >> src_num; + + ++src_num; + std::cerr << "src num is " << src_num << std::endl; + + // Write the new source number + src_number_file.seekg(0); + src_number_file << src_num; + + return src_num; +} + void MyFrontendAction::EndSourceFileAction() { @@ -134,13 +180,32 @@ MyFrontendAction::EndSourceFileAction() SourceLocation start = sm.getLocForStartOfFile(main_fid); std::string file_name = getCurrentFile(); + unsigned int src_number = get_src_number(); + std::stringstream ss; // Add declarations for coverage buffers int file_bytes = sm.getFileIDSize(main_fid); - ss << "unsigned int lines[" << file_bytes << "];" - << std::endl; - ss << "int size = " << file_bytes << ";" << std::endl; - ss << "char file_name[] = \"" << file_name << "\";" << std::endl; + + ss << "#include <scv_global.h>" << std::endl; + ss << "static unsigned int lines[" << file_bytes << "];" << std::endl; + + if (src_number != 0) { + unsigned int prev_src_number = src_number - 1; + ss << "extern struct scv_node node" << prev_src_number << ";" << std::endl; + } + + ss << "struct scv_node node" << src_number << " = {" << std::endl + << " .lines_ptr = lines," << std::endl + << " .size = " << file_bytes << "," << std::endl + << " .file_name = \"" << file_name << "\"," << std::endl; + if (src_number != 0) { + unsigned int prev_src_number = src_number - 1; + ss << " .next = &node" << prev_src_number << "," << std::endl; + } else { + ss << " .next = 0," << std::endl; + } + ss << "};" << std::endl; + TheRewriter.InsertTextAfter(start, ss.str()); // write the instrumented source file to another directory