citrun

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

commit a56fe4172259265658c0455df35fe8f00c9e9e63
parent 949e219a3af3bbe5020ceeb3aabaa45521c6e378
Author: Kyle Milz <kyle@0x30.net>
Date:   Fri, 16 Dec 2016 19:37:07 -0700

src: split TranslationUnit and ProcessFile

Diffstat:
Msrc/Jamfile | 3++-
Msrc/gl_main.cc | 4++--
Asrc/gl_procfile.cc | 130+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/gl_procfile.h | 30++++++++++++++++++++++++++++++
Asrc/gl_transunit.cc | 114+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/gl_transunit.h | 25+++++++++++++++++++++++++
Dsrc/process_file.cc | 223-------------------------------------------------------------------------------
Dsrc/process_file.h | 49-------------------------------------------------
8 files changed, 303 insertions(+), 275 deletions(-)

diff --git a/src/Jamfile b/src/Jamfile @@ -26,7 +26,8 @@ LINKLIBS on citrun-term += -lcurses ; # citrun-gl & citrun-gltest # GL_SRCS = - process_file.cc + gl_procfile.cc + gl_transunit.cc process_dir.cc gl_view.cc demo-atlas.cc diff --git a/src/gl_main.cc b/src/gl_main.cc @@ -8,7 +8,7 @@ #include "gl_font.h" #include "gl_view.h" #include "process_dir.h" -#include "process_file.h" +#include "gl_procfile.h" #include <GLFW/glfw3.h> @@ -62,7 +62,7 @@ main(int argc, char *argv[]) errx(1, "No support for OpenGL 2.0 found"); ProcessDir m_pdir; - std::vector<ProcessFile> drawables; + std::vector<GlProcessFile> drawables; demo_glstate_t *st = demo_glstate_create(); GlBuffer buffer; diff --git a/src/gl_procfile.cc b/src/gl_procfile.cc @@ -0,0 +1,130 @@ +// +// 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 <sys/mman.h> // mmap +#include <sys/stat.h> // S_IRUSR, S_IWUSR + +#include <cassert> +#include <csignal> // kill +#include <cstring> // strncmp +#include <err.h> +#include <fcntl.h> // O_RDONLY +#include <sstream> +#include <unistd.h> // getpagesize + +#include "gl_procfile.h" +#include "lib.h" // citrun_major, struct citrun_{node,header} + + +// +// Take a filesystem path and memory map its contents. Map at least a header +// structure on top of it. +// +GlProcessFile::GlProcessFile(std::string const &path, demo_font_t *font) : + m_path(path), + m_fd(0), + m_tus_with_execs(0) +{ + struct stat sb; + void *mem, *end; + + if ((m_fd = open(m_path.c_str(), O_RDONLY, S_IRUSR | S_IWUSR)) < 0) + err(1, "open"); + + if (fstat(m_fd, &sb) < 0) + err(1, "fstat"); + + // Explicitly check 0 here otherwise mmap barfs. + if (sb.st_size == 0 || sb.st_size > 1024 * 1024 * 1024) + errx(1, "invalid file size %lli", sb.st_size); + + m_size = sb.st_size; + + mem = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, m_fd, 0); + if (mem == MAP_FAILED) + err(1, "mmap"); + + // Header is always at offset 0 and always one page long. + m_header = static_cast<struct citrun_header *>(mem); + + assert(std::strncmp(m_header->magic, "ctrn", 4) == 0); + assert(m_header->major == citrun_major); + + std::stringstream ss; + ss << "Program Name:" << m_header->progname << std::endl; + ss << "Translation Units:" << m_header->units << std::endl; + ss << "Lines of Code:" << m_header->loc << std::endl; + ss << "Process Id:" << m_header->pids[0] << std::endl; + ss << "Parent Process Id:" << m_header->pids[1] << std::endl; + ss << "Process Group:" << m_header->pids[2] << std::endl; + + m_glbuffer.add_text(ss.str().c_str(), font, 2); + glyphy_point_t cur_pos; + m_glbuffer.current_point(&cur_pos); + + end = (char *)mem + m_size; + mem = (char *)mem + getpagesize(); + + while (mem < end) + m_tus.emplace_back(mem, font, cur_pos); + // Make sure internal increment in TranslationUnit works as intended. + assert(mem == end); +} + +// +// Checks if the pid given by the runtime is alive. Prone to race conditions. +// +bool +GlProcessFile::is_alive() const +{ + if (kill(m_header->pids[0], 0) == 0) + return 1; + return 0; +} + +const GlTranslationUnit * +GlProcessFile::find_tu(std::string const &srcname) const +{ + for (auto &i : m_tus) + if (srcname == i.comp_file_path()) + return &i; + return NULL; +} + +void +GlProcessFile::display() +{ + m_glbuffer.draw(); + + for (auto &t : m_tus) + t.display(); +} + +glyphy_extents_t +GlProcessFile::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/src/gl_procfile.h b/src/gl_procfile.h @@ -0,0 +1,30 @@ +#include <string> +#include <vector> + +#include "gl_buffer.h" +#include "gl_transunit.h" + + +// +// Owns an executing/executed instrumented processes shared memory file and gl +// buffer. +// +class GlProcessFile +{ + struct citrun_header *m_header; + std::string m_path; + int m_fd; + size_t m_size; + int m_tus_with_execs; + GlBuffer m_glbuffer; + +public: + GlProcessFile(std::string const &, demo_font_t *); + + const GlTranslationUnit *find_tu(std::string const &) const; + bool is_alive() const; + void display(); + glyphy_extents_t get_extents(); + + std::vector<GlTranslationUnit> m_tus; +}; diff --git a/src/gl_transunit.cc b/src/gl_transunit.cc @@ -0,0 +1,114 @@ +// +// 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> // memcpy +#include <err.h> +#include <fstream> +#include <iostream> +#include <unistd.h> // getpagesize + +#include "gl_transunit.h" +#include "lib.h" // struct citrun_node + + +// +// 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. +// +GlTranslationUnit::GlTranslationUnit(void* &mem, demo_font_t *font, + glyphy_point_t &cur_pos) : + m_node(static_cast<struct citrun_node *>(mem)), + m_data((unsigned long long *)(m_node + 1)), + m_data_buffer(new uint64_t[m_node->size]()) +{ + unsigned int size, page_mask; + + // Total size is node size plus live execution data size. + size = sizeof(struct citrun_node); + size += m_node->size * sizeof(unsigned long long); + + // Increment passed in pointer to next page. + page_mask = getpagesize() - 1; + mem = (char *)mem + ((size + page_mask) & ~page_mask); + + glyphy_point_t next_pos = cur_pos; + next_pos.x += 80; + m_glbuffer.move_to(&cur_pos); + + m_glbuffer.add_text(m_node->comp_file_path, font, 1); + + std::ifstream file_stream(m_node->abs_file_path); + if (file_stream.is_open() == 0) { + warnx("ifstream.open(%s)", m_node->abs_file_path); + return; + } + + std::string line; + unsigned int i; + for (i = 0; std::getline(file_stream, line); ++i) { + m_glbuffer.current_point(&cur_pos); + cur_pos.x = 0; + + m_glbuffer.move_to(&cur_pos); + //m_glbuffer.add_text(line.c_str(), font, 1); + } + + if (i != m_node->size) + warnx("%s size mismatch: %u vs %u", m_node->abs_file_path, i, + m_node->size); +} + +// +// Returns number of lines that citrun-inst processed (whole source file +// ideally) +// +unsigned int +GlTranslationUnit::num_lines() const +{ + return m_node->size; +} + +// +// Returns the source file path as it was passed to the compiler. +// +std::string +GlTranslationUnit::comp_file_path() const +{ + return std::string(m_node->comp_file_path); +} + +glyphy_extents_t +GlTranslationUnit::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 +GlTranslationUnit::save_executions() +{ + std::memcpy(m_data_buffer, m_data, m_node->size * sizeof(unsigned long long)); +} + +void +GlTranslationUnit::display() +{ + m_glbuffer.draw(); +} diff --git a/src/gl_transunit.h b/src/gl_transunit.h @@ -0,0 +1,25 @@ +#include <string> +#include <vector> + +#include "gl_buffer.h" + + +// +// Owns a few pages of shared memory and a gl buffer. +// +class GlTranslationUnit +{ + struct citrun_node *m_node; + uint64_t *m_data; + uint64_t *m_data_buffer; + GlBuffer m_glbuffer; + +public: + GlTranslationUnit(void* &, demo_font_t *, glyphy_point_t &); + + std::string comp_file_path() const; + unsigned int num_lines() const; + void save_executions(); + void display(); + glyphy_extents_t get_extents(); +}; diff --git a/src/process_file.cc b/src/process_file.cc @@ -1,223 +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 <sys/mman.h> // mmap -#include <sys/stat.h> // S_IRUSR - -#include <cassert> -#include <csignal> // kill -#include <cstring> // memcpy, strncmp -#include <err.h> -#include <fcntl.h> // O_RDONLY -#include <fstream> -#include <iostream> -#include <sstream> -#include <unistd.h> // getpagesize - -#include "process_file.h" -#include "lib.h" // citrun_major, struct citrun_{node,header} - - -// -// 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. -// -TranslationUnit::TranslationUnit(void* &mem, demo_font_t *font, - glyphy_point_t &cur_pos) : - m_node(static_cast<struct citrun_node *>(mem)), - m_data((unsigned long long *)(m_node + 1)), - m_data_buffer(new uint64_t[m_node->size]()) -{ - unsigned int size, page_mask; - - // Total size is node size plus live execution data size. - size = sizeof(struct citrun_node); - size += m_node->size * sizeof(unsigned long long); - - // Increment passed in pointer to next page. - page_mask = getpagesize() - 1; - mem = (char *)mem + ((size + page_mask) & ~page_mask); - - glyphy_point_t next_pos = cur_pos; - next_pos.x += 80; - m_glbuffer.move_to(&cur_pos); - - m_glbuffer.add_text(m_node->comp_file_path, font, 1); - - std::ifstream file_stream(m_node->abs_file_path); - if (file_stream.is_open() == 0) { - warnx("ifstream.open(%s)", m_node->abs_file_path); - return; - } - - std::string line; - unsigned int i; - for (i = 0; std::getline(file_stream, line); ++i) { - m_glbuffer.current_point(&cur_pos); - cur_pos.x = 0; - - m_glbuffer.move_to(&cur_pos); - //m_glbuffer.add_text(line.c_str(), font, 1); - } - - if (i != m_node->size) - warnx("%s size mismatch: %u vs %u", m_node->abs_file_path, i, - m_node->size); -} - -// -// Returns number of lines that citrun-inst processed (whole source file -// ideally) -// -unsigned int -TranslationUnit::num_lines() const -{ - return m_node->size; -} - -// -// Returns the source file path as it was passed to the compiler. -// -std::string -TranslationUnit::comp_file_path() const -{ - return std::string(m_node->comp_file_path); -} - -glyphy_extents_t -TranslationUnit::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 -TranslationUnit::save_executions() -{ - std::memcpy(m_data_buffer, m_data, m_node->size * sizeof(unsigned long long)); -} - -void -TranslationUnit::display() -{ - m_glbuffer.draw(); -} - - -// -// Take a filesystem path and memory map its contents. Map at least a header -// structure on top of it. -// -ProcessFile::ProcessFile(std::string const &path, demo_font_t *font) : - m_path(path), - m_fd(0), - m_tus_with_execs(0) -{ - struct stat sb; - void *mem, *end; - - if ((m_fd = open(m_path.c_str(), O_RDONLY, S_IRUSR | S_IWUSR)) < 0) - err(1, "open"); - - if (fstat(m_fd, &sb) < 0) - err(1, "fstat"); - - // Explicitly check 0 here otherwise mmap barfs. - if (sb.st_size == 0 || sb.st_size > 1024 * 1024 * 1024) - errx(1, "invalid file size %lli", sb.st_size); - - m_size = sb.st_size; - - mem = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, m_fd, 0); - if (mem == MAP_FAILED) - err(1, "mmap"); - - // Header is always at offset 0 and always one page long. - m_header = static_cast<struct citrun_header *>(mem); - - assert(std::strncmp(m_header->magic, "ctrn", 4) == 0); - assert(m_header->major == citrun_major); - - std::stringstream ss; - ss << "Program Name:" << m_header->progname << std::endl; - ss << "Translation Units:" << m_header->units << std::endl; - ss << "Lines of Code:" << m_header->loc << std::endl; - ss << "Process Id:" << m_header->pids[0] << std::endl; - ss << "Parent Process Id:" << m_header->pids[1] << std::endl; - ss << "Process Group:" << m_header->pids[2] << std::endl; - - m_glbuffer.add_text(ss.str().c_str(), font, 2); - glyphy_point_t cur_pos; - m_glbuffer.current_point(&cur_pos); - - end = (char *)mem + m_size; - mem = (char *)mem + getpagesize(); - - while (mem < end) - m_tus.emplace_back(mem, font, cur_pos); - // Make sure internal increment in TranslationUnit works as intended. - assert(mem == end); -} - -// -// Checks if the pid given by the runtime is alive. Prone to race conditions. -// -bool -ProcessFile::is_alive() const -{ - if (kill(m_header->pids[0], 0) == 0) - return 1; - return 0; -} - -const TranslationUnit * -ProcessFile::find_tu(std::string const &srcname) const -{ - for (auto &i : m_tus) - if (srcname == i.comp_file_path()) - return &i; - return NULL; -} - -void -ProcessFile::display() -{ - m_glbuffer.draw(); - - for (auto &t : m_tus) - t.display(); -} - -glyphy_extents_t -ProcessFile::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/src/process_file.h b/src/process_file.h @@ -1,49 +0,0 @@ -#include <string> -#include <vector> - -#include "gl_buffer.h" - - -// -// Owns a few pages of shared memory that are created by a running instrumented -// translation unit. -// -class TranslationUnit -{ - struct citrun_node *m_node; - uint64_t *m_data; - uint64_t *m_data_buffer; - GlBuffer m_glbuffer; - -public: - TranslationUnit(void* &, demo_font_t *, 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. -// -class ProcessFile -{ - struct citrun_header *m_header; - std::string m_path; - int m_fd; - size_t m_size; - int m_tus_with_execs; - GlBuffer m_glbuffer; - -public: - ProcessFile(std::string const &, demo_font_t *); - - const TranslationUnit *find_tu(std::string const &) const; - bool is_alive() const; - void display(); - glyphy_extents_t get_extents(); - - std::vector<TranslationUnit> m_tus; -};