citrun

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

commit 111b043430b7e6d430bce6620baf55450505993c
parent 03b52c91db0fa0d104108f0a0503608a62a8d0ed
Author: Kyle Milz <kyle@0x30.net>
Date:   Mon,  9 Oct 2017 23:14:24 -0600

bin: fold 3 separate classes into gl_runtime

Diffstat:
Mbin/Jamfile | 6++----
Mbin/gl_main.h | 3+--
Dbin/gl_procfile.cc | 107-------------------------------------------------------------------------------
Dbin/gl_procfile.h | 41-----------------------------------------
Abin/gl_runtime.cc | 255+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Abin/gl_runtime.h | 91+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dbin/gl_transunit.cc | 116-------------------------------------------------------------------------------
Dbin/gl_transunit.h | 31-------------------------------
Dbin/process_dir.cc | 52----------------------------------------------------
Dbin/process_dir.h | 22----------------------
10 files changed, 349 insertions(+), 375 deletions(-)

diff --git a/bin/Jamfile b/bin/Jamfile @@ -62,11 +62,9 @@ GL_SRCS = gl_buffer.cc gl_font.cc gl_main.cc - gl_procfile.cc - gl_transunit.cc + gl_runtime.cc gl_view.cc - matrix4x4.c - process_dir.cc ; + matrix4x4.c ; Library gl_common : $(GL_SRCS) ; diff --git a/bin/gl_main.h b/bin/gl_main.h @@ -2,9 +2,8 @@ #include "gl_buffer.h" // citrun::gl_buffer #include "gl_font.h" // citrun::gl_font -#include "gl_procfile.h" // citrun::gl_procfile +#include "gl_runtime.h" // citrun::gl_procfile, citrun::process_dir #include "gl_view.h" -#include "process_dir.h" // citrun::process_dir namespace citrun { diff --git a/bin/gl_procfile.cc b/bin/gl_procfile.cc @@ -1,107 +0,0 @@ -// -// Copyright (c) 2016 Kyle Milz <kyle@0x30.net> -// -// Permission to use, copy, modify, and distribute this software for any -// purpose with or without fee is hereby granted, provided that the above -// copyright notice and this permission notice appear in all copies. -// -// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -// -#include <cassert> // assert -#include <csignal> // kill -#include <cstring> // std::strncmp -#include <sstream> // std::stringstream - -#include "lib.h" // citrun_major, struct citrun_{node,header} -#include "gl_procfile.h" // citrun::gl_procfile - - -// -// Take a filesystem path and memory map its contents. Map at least a header -// structure on top of it. -// -citrun::gl_procfile::gl_procfile(std::string const &path, citrun::gl_font &font, double const &x_off) : - m_mem(path) -{ - // Header is always at offset 0. - m_header = static_cast<struct citrun_header *>(m_mem.get_ptr()); - m_mem.increment(sizeof(struct citrun_header)); - - assert(std::strncmp(m_header->magic, "ctrn", 4) == 0); - assert(m_header->major == citrun_major); - - glyphy_point_t orig_pos = { x_off, 0 }; - m_glbuffer.move_to(&orig_pos); - - std::stringstream maj; - maj << "Name: '" << m_header->progname << "'" << std::endl; - maj << "Translation Units: " << m_header->units << std::endl; - maj << "Lines of code: " << m_header->loc << std::endl; - m_glbuffer.add_text(maj.str().c_str(), font, 3); - - std::stringstream min; - min << "Working directory: " << m_header->cwd << std::endl; - min << "Instrumented with: v" << m_header->major << "." << m_header->minor << std::endl; - m_glbuffer.add_text(min.str().c_str(), font, 2); - - glyphy_point_t draw_pos; - m_glbuffer.current_point(&draw_pos); - - while (!m_mem.at_end()) { - m_tus.emplace_back(m_mem, font, draw_pos); - draw_pos.x += 80; - } - - // Make sure internal increment in TranslationUnit works as intended. - assert(m_mem.at_end_exactly()); -} - -// -// Checks if the pid given by the runtime is alive. Prone to race conditions. -// -bool -citrun::gl_procfile::is_alive() const -{ - return kill(m_header->pids[0], 0) == 0; -} - -const citrun::gl_transunit * -citrun::gl_procfile::find_tu(std::string const &srcname) const -{ - for (auto &i : m_tus) - if (srcname == i.comp_file_path()) - return &i; - return NULL; -} - -void -citrun::gl_procfile::display() -{ - m_glbuffer.draw(); - - for (auto &t : m_tus) - t.display(); -} - -glyphy_extents_t -citrun::gl_procfile::get_extents() -{ - glyphy_extents_t extents; - m_glbuffer.extents(NULL, &extents); - - for (auto &i : m_tus) { - glyphy_extents_t t = i.get_extents(); - extents.max_x = std::max(extents.max_x, t.max_x); - extents.max_y = std::max(extents.max_y, t.max_y); - extents.min_x = std::min(extents.min_x, t.min_x); - extents.min_y = std::min(extents.min_y, t.min_y); - } - - return extents; -} diff --git a/bin/gl_procfile.h b/bin/gl_procfile.h @@ -1,41 +0,0 @@ -#include <string> // std::string -#include <vector> // std::vector - -#include "gl_font.h" // citrun::gl_font -#include "gl_buffer.h" // citrun::gl_buffer -#include "gl_transunit.h" // citrun::gl_transunit -#ifdef _WIN32 -#include "mem_win32.h" -#else -#include "mem_unix.h" // citrun::mem_unix -#endif - - -namespace citrun { - -// -// Owns an executing/executed instrumented processes shared memory file and gl -// buffer. -// -class gl_procfile -{ - struct citrun_header *m_header; - citrun::gl_buffer m_glbuffer; -#ifdef _WIN32 - MemWin32 m_mem; -#else - citrun::mem_unix m_mem; -#endif - -public: - gl_procfile(std::string const&, citrun::gl_font &, double const&); - - const citrun::gl_transunit *find_tu(std::string const &) const; - bool is_alive() const; - void display(); - glyphy_extents_t get_extents(); - - std::vector<citrun::gl_transunit> m_tus; -}; - -} // namespace citrun diff --git a/bin/gl_runtime.cc b/bin/gl_runtime.cc @@ -0,0 +1,255 @@ +// +// Copyright (c) 2016, 2017 Kyle Milz <kyle@0x30.net> +// +// Permission to use, copy, modify, and distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +// +#include <sys/stat.h> + +#include <cassert> // assert +#include <cstdlib> // std::getenv +#include <cstring> // std::memcpy, std::strncmp +#include <csignal> // kill +#include <err.h> +#include <fstream> // std::ifstream +#include <iostream> // std::cerr +#include <sstream> // std::stringstream + +#include "lib.h" // struct citrun_node +#include "gl_runtime.h" // citrun::gl_transunit, citrun::gl_procfile + + +// +// Take a pointer to a shared memory region and map data structures on top. +// Automatically increments the pointer once we know how big this region is. +// +citrun::gl_transunit::gl_transunit(citrun::mem &m_mem, citrun::gl_font &font, + glyphy_point_t &draw_pos) : + m_node(static_cast<struct citrun_node *>(m_mem.get_ptr())), + m_data((unsigned long long *)(m_node + 1)), + m_data_buffer(m_node->size) +{ + unsigned int size; + + // Total size is node size plus live execution data size. + size = sizeof(struct citrun_node); + size += m_node->size * sizeof(unsigned long long); + m_mem.increment(size); + + m_glbuffer.move_to(&draw_pos); + + std::stringstream tu_info; + tu_info << "Source file: " << m_node->comp_file_path << std::endl; + tu_info << "Lines of code: " << m_node->size << std::endl; + m_glbuffer.add_text(tu_info.str().c_str(), font, 2); + + glyphy_point_t cur_pos; + m_glbuffer.current_point(&cur_pos); + cur_pos.x = draw_pos.x; + m_glbuffer.move_to(&cur_pos); + + std::ifstream file_stream(m_node->abs_file_path); + if (file_stream.is_open() == 0) { + std::cerr << "ifstream.open: " << m_node->abs_file_path << std::endl; + return; + } + + std::string line; + unsigned int i; + for (i = 1; std::getline(file_stream, line); ++i) { + m_glbuffer.add_text(line.c_str(), font, 1); + + m_glbuffer.current_point(&cur_pos); + cur_pos.x = draw_pos.x; + m_glbuffer.move_to(&cur_pos); + } + + if (i != m_node->size) + std::cerr << m_node->abs_file_path << " size mismatch: " + << i << " vs " << m_node->size << std::endl; +} + +// +// Returns number of lines that citrun_inst processed (whole source file +// ideally) +// +unsigned int +citrun::gl_transunit::num_lines() const +{ + return m_node->size; +} + +// +// Returns the source file path as it was passed to the compiler. +// +std::string +citrun::gl_transunit::comp_file_path() const +{ + return std::string(m_node->comp_file_path); +} + +glyphy_extents_t +citrun::gl_transunit::get_extents() +{ + glyphy_extents_t extents; + m_glbuffer.extents(NULL, &extents); + + return extents; +} + +// +// Copy live executions to secondary buffer. Used for computing deltas later. +// +void +citrun::gl_transunit::save_executions() +{ + std::memcpy(&m_data_buffer[0], m_data, m_node->size * sizeof(unsigned long long)); +} + +void +citrun::gl_transunit::display() +{ + m_glbuffer.draw(); +} + +// +// citrun::gl_procfile +// +// Take a filesystem path and memory map its contents. Map at least a header +// structure on top of it. +// +citrun::gl_procfile::gl_procfile(std::string const &path, citrun::gl_font &font, double const &x_off) : + m_mem(path) +{ + // Header is always at offset 0. + m_header = static_cast<struct citrun_header *>(m_mem.get_ptr()); + m_mem.increment(sizeof(struct citrun_header)); + + assert(std::strncmp(m_header->magic, "ctrn", 4) == 0); + assert(m_header->major == citrun_major); + + glyphy_point_t orig_pos = { x_off, 0 }; + m_glbuffer.move_to(&orig_pos); + + std::stringstream maj; + maj << "Name: '" << m_header->progname << "'" << std::endl; + maj << "Translation Units: " << m_header->units << std::endl; + maj << "Lines of code: " << m_header->loc << std::endl; + m_glbuffer.add_text(maj.str().c_str(), font, 3); + + std::stringstream min; + min << "Working directory: " << m_header->cwd << std::endl; + min << "Instrumented with: v" << m_header->major << "." << m_header->minor << std::endl; + m_glbuffer.add_text(min.str().c_str(), font, 2); + + glyphy_point_t draw_pos; + m_glbuffer.current_point(&draw_pos); + + while (!m_mem.at_end()) { + m_tus.emplace_back(m_mem, font, draw_pos); + draw_pos.x += 80; + } + + // Make sure internal increment in TranslationUnit works as intended. + assert(m_mem.at_end_exactly()); +} + +// +// Checks if the pid given by the runtime is alive. Prone to race conditions. +// +bool +citrun::gl_procfile::is_alive() const +{ + return kill(m_header->pids[0], 0) == 0; +} + +const citrun::gl_transunit * +citrun::gl_procfile::find_tu(std::string const &srcname) const +{ + for (auto &i : m_tus) + if (srcname == i.comp_file_path()) + return &i; + return NULL; +} + +void +citrun::gl_procfile::display() +{ + m_glbuffer.draw(); + + for (auto &t : m_tus) + t.display(); +} + +glyphy_extents_t +citrun::gl_procfile::get_extents() +{ + glyphy_extents_t extents; + m_glbuffer.extents(NULL, &extents); + + for (auto &i : m_tus) { + glyphy_extents_t t = i.get_extents(); + extents.max_x = std::max(extents.max_x, t.max_x); + extents.max_y = std::max(extents.max_y, t.max_y); + extents.min_x = std::min(extents.min_x, t.min_x); + extents.min_y = std::min(extents.min_y, t.min_y); + } + + return extents; +} + + +// +// citrun::process_dir +// +citrun::process_dir::process_dir() +{ + if ((m_procdir = std::getenv("CITRUN_PROCDIR")) == NULL) + m_procdir = "/tmp/citrun/"; + + if ((m_dirp = opendir(m_procdir)) == NULL) { + if (errno != ENOENT) + err(1, "opendir '%s'", m_procdir); + + // Create if there was no such file or directory. + mkdir(m_procdir, S_IRWXU); + if ((m_dirp = opendir(m_procdir)) == NULL) + err(1, "opendir '%s'", m_procdir); + } +} + +std::vector<std::string> +citrun::process_dir::scan() +{ + std::vector<std::string> new_files; + struct dirent *dp; + + rewinddir(m_dirp); + while ((dp = readdir(m_dirp)) != NULL) { + + if (std::strcmp(dp->d_name, ".") == 0 || + std::strcmp(dp->d_name, "..") == 0) + continue; + + std::string p(m_procdir); + p.append(dp->d_name); + + if (m_known_files.find(p) != m_known_files.end()) + // We already know this file. + continue; + + m_known_files.insert(p); + new_files.push_back(p); + } + + return new_files; +} diff --git a/bin/gl_runtime.h b/bin/gl_runtime.h @@ -0,0 +1,91 @@ +// +// Copyright (c) 2017 Kyle Milz <kyle.milz@gmail.com> +// +// Permission to use, copy, modify, and distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +// +#include <sys/types.h> + +#include <dirent.h> // DIR, opendir, readdir +#include <string> // std::string +#include <unordered_set> // std::unordered_set +#include <vector> // std::vector + +#include "gl_buffer.h" // citrun::gl_buffer +#include "gl_font.h" // citrun::gl_font +#include "mem.h" // citrun::mem +#ifdef _WIN32 +#include "mem_win32.h" +#else +#include "mem_unix.h" // citrun::mem_unix +#endif + + +namespace citrun { + +// +// Owns a few pages of shared memory and a gl buffer. +// +class gl_transunit { +private: + struct citrun_node *m_node; + uint64_t *m_data; + std::vector<uint64_t> m_data_buffer; + citrun::gl_buffer m_glbuffer; + +public: + gl_transunit(citrun::mem &, citrun::gl_font &, glyphy_point_t &); + + std::string comp_file_path() const; + unsigned int num_lines() const; + void save_executions(); + void display(); + glyphy_extents_t get_extents(); +}; + +// +// Owns an executing/executed instrumented processes shared memory file and +// gl_buffer. +// +class gl_procfile { +private: + struct citrun_header *m_header; + citrun::gl_buffer m_glbuffer; +#ifdef _WIN32 + MemWin32 m_mem; +#else + citrun::mem_unix m_mem; +#endif + +public: + gl_procfile(std::string const&, citrun::gl_font &, double const&); + + const citrun::gl_transunit *find_tu(std::string const &) const; + bool is_alive() const; + void display(); + glyphy_extents_t get_extents(); + + std::vector<citrun::gl_transunit> m_tus; +}; + +class process_dir { +private: + const char *m_procdir; + DIR *m_dirp; + std::unordered_set<std::string> m_known_files; + +public: + process_dir(); + std::vector<std::string> scan(); +}; + +} // namespace citrun diff --git a/bin/gl_transunit.cc b/bin/gl_transunit.cc @@ -1,116 +0,0 @@ -// -// Copyright (c) 2016 Kyle Milz <kyle@0x30.net> -// -// Permission to use, copy, modify, and distribute this software for any -// purpose with or without fee is hereby granted, provided that the above -// copyright notice and this permission notice appear in all copies. -// -// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -// -#include <cstring> // std::memcpy -#include <fstream> // std::ifstream -#include <iostream> // std::cerr -#include <sstream> // std::stringstream - -#include "lib.h" // struct citrun_node -#include "gl_transunit.h" // citrun::gl_transunit - - -// -// Take a pointer to a shared memory region and map data structures on top. -// Automatically increments the pointer once we know how big this region is. -// -citrun::gl_transunit::gl_transunit(citrun::mem &m_mem, citrun::gl_font &font, - glyphy_point_t &draw_pos) : - m_node(static_cast<struct citrun_node *>(m_mem.get_ptr())), - m_data((unsigned long long *)(m_node + 1)), - m_data_buffer(m_node->size) -{ - unsigned int size; - - // Total size is node size plus live execution data size. - size = sizeof(struct citrun_node); - size += m_node->size * sizeof(unsigned long long); - m_mem.increment(size); - - m_glbuffer.move_to(&draw_pos); - - std::stringstream tu_info; - tu_info << "Source file: " << m_node->comp_file_path << std::endl; - tu_info << "Lines of code: " << m_node->size << std::endl; - m_glbuffer.add_text(tu_info.str().c_str(), font, 2); - - glyphy_point_t cur_pos; - m_glbuffer.current_point(&cur_pos); - cur_pos.x = draw_pos.x; - m_glbuffer.move_to(&cur_pos); - - std::ifstream file_stream(m_node->abs_file_path); - if (file_stream.is_open() == 0) { - std::cerr << "ifstream.open: " << m_node->abs_file_path << std::endl; - return; - } - - std::string line; - unsigned int i; - for (i = 1; std::getline(file_stream, line); ++i) { - m_glbuffer.add_text(line.c_str(), font, 1); - - m_glbuffer.current_point(&cur_pos); - cur_pos.x = draw_pos.x; - m_glbuffer.move_to(&cur_pos); - } - - if (i != m_node->size) - std::cerr << m_node->abs_file_path << " size mismatch: " - << i << " vs " << m_node->size << std::endl; -} - -// -// Returns number of lines that citrun_inst processed (whole source file -// ideally) -// -unsigned int -citrun::gl_transunit::num_lines() const -{ - return m_node->size; -} - -// -// Returns the source file path as it was passed to the compiler. -// -std::string -citrun::gl_transunit::comp_file_path() const -{ - return std::string(m_node->comp_file_path); -} - -glyphy_extents_t -citrun::gl_transunit::get_extents() -{ - glyphy_extents_t extents; - m_glbuffer.extents(NULL, &extents); - - return extents; -} - -// -// Copy live executions to secondary buffer. Used for computing deltas later. -// -void -citrun::gl_transunit::save_executions() -{ - std::memcpy(&m_data_buffer[0], m_data, m_node->size * sizeof(unsigned long long)); -} - -void -citrun::gl_transunit::display() -{ - m_glbuffer.draw(); -} diff --git a/bin/gl_transunit.h b/bin/gl_transunit.h @@ -1,31 +0,0 @@ -#include <string> // std::string -#include <vector> // std::vector - -#include "gl_buffer.h" // citrun::gl_buffer -#include "gl_font.h" // citrun::gl_font -#include "mem.h" // citrun::mem - - -namespace citrun { - -// -// Owns a few pages of shared memory and a gl buffer. -// -class gl_transunit -{ - struct citrun_node *m_node; - uint64_t *m_data; - std::vector<uint64_t> m_data_buffer; - citrun::gl_buffer m_glbuffer; - -public: - gl_transunit(citrun::mem &, citrun::gl_font &, glyphy_point_t &); - - std::string comp_file_path() const; - unsigned int num_lines() const; - void save_executions(); - void display(); - glyphy_extents_t get_extents(); -}; - -} // namespace citrun diff --git a/bin/process_dir.cc b/bin/process_dir.cc @@ -1,52 +0,0 @@ -#include "process_dir.h" - -#include <err.h> -#include <cstdlib> // getenv -#include <cstring> -#include <iostream> - -#include <sys/stat.h> - - -citrun::process_dir::process_dir() -{ - if ((m_procdir = std::getenv("CITRUN_PROCDIR")) == NULL) - m_procdir = "/tmp/citrun/"; - - if ((m_dirp = opendir(m_procdir)) == NULL) { - if (errno != ENOENT) - err(1, "opendir '%s'", m_procdir); - - // Create if there was no such file or directory. - mkdir(m_procdir, S_IRWXU); - if ((m_dirp = opendir(m_procdir)) == NULL) - err(1, "opendir '%s'", m_procdir); - } -} - -std::vector<std::string> -citrun::process_dir::scan() -{ - std::vector<std::string> new_files; - struct dirent *dp; - - rewinddir(m_dirp); - while ((dp = readdir(m_dirp)) != NULL) { - - if (std::strcmp(dp->d_name, ".") == 0 || - std::strcmp(dp->d_name, "..") == 0) - continue; - - std::string p(m_procdir); - p.append(dp->d_name); - - if (m_known_files.find(p) != m_known_files.end()) - // We already know this file. - continue; - - m_known_files.insert(p); - new_files.push_back(p); - } - - return new_files; -} diff --git a/bin/process_dir.h b/bin/process_dir.h @@ -1,22 +0,0 @@ -#include <sys/types.h> - -#include <dirent.h> // DIR, opendir, readdir -#include <string> -#include <unordered_set> -#include <vector> - - -namespace citrun { - -class process_dir -{ - const char *m_procdir; - DIR *m_dirp; - std::unordered_set<std::string> m_known_files; - -public: - process_dir(); - std::vector<std::string> scan(); -}; - -} // namespace citrun