Skip to content

Commit

Permalink
Merge pull request #62 from AjayBrahmakshatriya/master
Browse files Browse the repository at this point in the history
Added support for D2X debugging
  • Loading branch information
AjayBrahmakshatriya authored Jan 3, 2024
2 parents 6e7e4a1 + 29552a7 commit 40013df
Show file tree
Hide file tree
Showing 15 changed files with 217 additions and 25 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "deps/d2x"]
path = deps/d2x
url = https://github.com/BuildIt-lang/d2x.git
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ all: executables

CHECK_CONFIG=1
CONFIG_STR=DEBUG=$(DEBUG) RECOVER_VAR_NAMES=$(RECOVER_VAR_NAMES) TRACER_USE_LIBUNWIND=$(TRACER_USE_LIBUNWIND)
CONFIG_STR+=EXTRA_CFLAGS=$(EXTRA_CFLAGS)
CONFIG_STR+=EXTRA_CFLAGS=$(EXTRA_CFLAGS) ENABLE_D2X=$(ENABLE_D2X)


# Create a scratch directory where the files are stored
Expand All @@ -19,6 +19,7 @@ $(shell mkdir -p $(BASE_DIR)/scratch)
include make/pkgconfig.mk
include make/format.mk
include make/stable_config.mk
include make/deps.mk
include make/buildit_rules.mk
include make/tests.mk

Expand Down
1 change: 1 addition & 0 deletions deps/d2x
Submodule d2x added at ce44db
25 changes: 25 additions & 0 deletions include/blocks/c_code_generator.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
#ifndef C_CODE_GENERATOR_H
#define C_CODE_GENERATOR_H

#ifdef ENABLE_D2X
#include "d2x/d2x.h"
#include "d2x/utils.h"
#endif

#include "blocks/block_visitor.h"
#include "blocks/stmt.h"
#include "builder/dyn_var.h"
Expand All @@ -18,6 +24,14 @@ class c_code_generator : public block_visitor {
std::ostream &oss;
int curr_indent = 0;
bool decl_only = false;
bool use_d2x = false;

#ifdef ENABLE_D2X
d2x::d2x_context xctx;
#endif
void save_static_info(block::Ptr a);
void nextl(void);

virtual void visit(not_expr::Ptr);
virtual void visit(and_expr::Ptr);
virtual void visit(bitwise_and_expr::Ptr);
Expand Down Expand Up @@ -78,6 +92,17 @@ class c_code_generator : public block_visitor {
ast->accept(&generator);
oss << std::endl;
}
static void generate_code_d2x(block::Ptr ast, std::ostream &oss, int indent = 0, bool decl_only = false) {
#ifndef ENABLE_D2X
assert(false && "Cannot generate code with D2X support without ENABLE_D2X build option");
#endif
c_code_generator generator(oss);
generator.use_d2x = true;
generator.decl_only = decl_only;
generator.curr_indent = indent;
ast->accept(&generator);
oss << std::endl;
}
template <typename T>
static void generate_struct_decl(std::ostream &oss, int indent = 0) {
static_assert(std::is_base_of<builder::var, T>::value, "Template argument should be a dyn_var");
Expand Down
9 changes: 8 additions & 1 deletion include/builder/builder_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,17 @@ block::expr::Ptr create_foreign_expr(const T t);
template <typename T>
builder create_foreign_expr_builder(const T t);

class static_var_base;

class tracking_tuple {
public:
const unsigned char *ptr;
uint32_t size;
tracking_tuple(const unsigned char *_ptr, uint32_t _size) : ptr(_ptr), size(_size) {}
static_var_base *var_ref;

tracking_tuple(const unsigned char *_ptr, uint32_t _size, static_var_base *_var_ref)
: ptr(_ptr), size(_size), var_ref(_var_ref) {}

std::string snapshot(void) {
std::string output_string;
char temp[4];
Expand Down Expand Up @@ -71,6 +77,7 @@ class builder_context {
bool dynamic_use_cxx = false;
std::string dynamic_compiler_flags = "";
std::string dynamic_header_includes = "";
bool enable_d2x = false;

bool is_visited_tag(tracer::tag &new_tag);
void erase_tag(tracer::tag &erase_tag);
Expand Down
56 changes: 49 additions & 7 deletions include/builder/static_var.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,26 @@

#include "builder/builder.h"
#include "builder/builder_context.h"
#include "util/var_finder.h"

#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
#define MAX_TRACKING_VAR_SIZE (128)

namespace builder {

// Base class for all static vars
class static_var_base {
public:
mutable std::string var_name;
virtual std::string serialize() {
return "";
}
virtual ~static_var_base() {}
};

template <typename T>
class static_var {
class static_var : static_var_base {
public:
static_assert(std::is_same<T, short int>::value || std::is_same<T, unsigned short int>::value ||
std::is_same<T, int>::value || std::is_same<T, unsigned int>::value ||
Expand All @@ -24,8 +35,19 @@ class static_var {
"= " TOSTRING(MAX_TRACKING_VARIABLE_SIZE));
T val;

mutable bool name_checked = false;
void try_get_name() const {
if (builder_context::current_builder_context->enable_d2x == false)
return;
if (var_name == "" && name_checked == false) {
var_name = util::find_variable_name(const_cast<void *>(static_cast<const void *>(this)));
}
}

static_var(const static_var &other) : static_var((T)other) {}
static_var &operator=(const static_var &other) {
try_get_name();
name_checked = true;
*this = (T)other;
return *this;
}
Expand All @@ -34,30 +56,40 @@ class static_var {
static_var(const static_var<OT> &other) : static_var((T)(OT)other) {}
template <typename OT>
static_var &operator=(const static_var<OT> &other) {
try_get_name();
name_checked = true;
*this = (T)(OT)other;
return *this;
}

operator T &() {
try_get_name();
name_checked = true;
return val;
}
operator const T &() const {
try_get_name();
name_checked = true;
return val;
}
const T &operator=(const T &t) {
try_get_name();
name_checked = true;
val = t;
return t;
}
static_var() {
assert(builder_context::current_builder_context != nullptr);
builder_context::current_builder_context->static_var_tuples.push_back(
tracking_tuple((unsigned char *)&val, sizeof(T)));
tracking_tuple((unsigned char *)&val, sizeof(T), this));
try_get_name();
}
static_var(const T &v) {
assert(builder_context::current_builder_context != nullptr);
builder_context::current_builder_context->static_var_tuples.push_back(
tracking_tuple((unsigned char *)&val, sizeof(T)));
tracking_tuple((unsigned char *)&val, sizeof(T), this));
val = v;
try_get_name();
}
~static_var() {
assert(builder_context::current_builder_context != nullptr);
Expand All @@ -66,12 +98,16 @@ class static_var {
builder_context::current_builder_context->static_var_tuples.pop_back();
}
operator builder() {
try_get_name();
return (builder)val;
}
virtual std::string serialize() override {
return std::to_string(val);
}
};

template <typename T>
class static_var<T[]> {
class static_var<T[]> : static_var_base {
public:
static_assert(std::is_same<T, short int>::value || std::is_same<T, unsigned short int>::value ||
std::is_same<T, int>::value || std::is_same<T, unsigned int>::value ||
Expand All @@ -94,32 +130,35 @@ class static_var<T[]> {
return val[index];
}
static_var() {
var_name = "ArrayVar";
assert(builder_context::current_builder_context != nullptr);
// This val _should_ not be used. But we will insert it to hold place
// for this static var in the list of tuples, otherwise destructor order will be weird
val = new T[1];

builder_context::current_builder_context->static_var_tuples.push_back(
tracking_tuple((unsigned char *)val, 1));
tracking_tuple((unsigned char *)val, 1, this));
}
static_var(const std::initializer_list<T> &list) {
var_name = "ArrayVar";
assert(builder_context::current_builder_context != nullptr);
val = new T[list.size()];
builder_context::current_builder_context->static_var_tuples.push_back(
tracking_tuple((unsigned char *)val, sizeof(T) * list.size()));
tracking_tuple((unsigned char *)val, sizeof(T) * list.size(), this));
for (int i = 0; i < list.size(); i++) {
val[i] = list[i];
}
}
void resize(size_t s) {
var_name = "ArrayVar";
T *new_ptr = new T[s];
assert(builder_context::current_builder_context != nullptr);
assert(builder_context::current_builder_context->static_var_tuples.size() > 0);
for (size_t i = 0; i < builder_context::current_builder_context->static_var_tuples.size(); i++) {
if (builder_context::current_builder_context->static_var_tuples[i].ptr ==
(unsigned char *)val) {
builder_context::current_builder_context->static_var_tuples[i] =
tracking_tuple((unsigned char *)new_ptr, sizeof(T) * s);
tracking_tuple((unsigned char *)new_ptr, sizeof(T) * s, this);
break;
}
}
Expand All @@ -133,6 +172,9 @@ class static_var<T[]> {
builder_context::current_builder_context->static_var_tuples.pop_back();
delete[] val;
}
virtual std::string serialize() override {
return "<array>";
}
};
} // namespace builder
#endif
1 change: 1 addition & 0 deletions include/util/tracer.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class tag {
public:
std::vector<unsigned long long> pointers;
std::vector<std::string> static_var_snapshots;
std::vector<std::pair<std::string, std::string>> static_var_key_values;

bool operator==(const tag &other) {
if (other.pointers.size() != pointers.size())
Expand Down
8 changes: 4 additions & 4 deletions make/buildit_rules.mk
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@ $(BUILD_DIR)/gen_headers/gen/compiler_headers.h:
@echo "#define GEN_TEMPLATE_NAME \"$(BASE_DIR)/scratch/code_XXXXXX\"" >> $@
@echo "#define COMPILER_PATH \"$(CC)\"" >> $@
@echo "#define CXX_COMPILER_PATH \"$(CXX)\"" >> $@
$(LIBRARY_OBJS): $(BUILD_DIR)/%.o: $(SRC_DIR)/%.cpp $(INCLUDES)
$(LIBRARY_OBJS): $(BUILD_DIR)/%.o: $(SRC_DIR)/%.cpp $(INCLUDES) $(DEPS_LIST)
@mkdir -p $(@D)
$(CXXV) $(CFLAGS_INTERNAL) $(CFLAGS) $< -o $@ $(INCLUDE_FLAGS) -c
$(BUILD_DIR)/samples/%.o: $(SAMPLES_DIR)/%.cpp $(INCLUDES)
$(BUILD_DIR)/samples/%.o: $(SAMPLES_DIR)/%.cpp $(INCLUDES) $(DEPS_LIST)
@mkdir -p $(@D)
$(CXXV) $(CFLAGS_INTERNAL) $(CFLAGS) $< -o $@ $(INCLUDE_FLAGS) -c
$(LIBRARY): $(LIBRARY_OBJS)
$(LIBRARY): $(LIBRARY_OBJS) $(DEPS_LIST)
@mkdir -p $(@D)
$(ARV) cr $(LIBRARY) $(LIBRARY_OBJS)
$(BUILD_DIR)/sample%: $(BUILD_DIR)/samples/sample%.o $(LIBRARY)
$(BUILD_DIR)/sample%: $(BUILD_DIR)/samples/sample%.o $(LIBRARY) $(DEPS_LIST)
@mkdir -p $(@D)
$(CXXLDV) -o $@ $< $(LINKER_FLAGS)

Expand Down
8 changes: 8 additions & 0 deletions make/deps.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Build dependencies as required

# D2X
# this d2x.dep is a representative of everything
# that d2x provides
$(BUILD_DIR)/d2x.dep: $(D2X_DEPS) $(INCLUDES)
$(MAKE) -C $(D2X_DIR) BUILDIT_DIR=$(BASE_DIR) lib
touch $(BUILD_DIR)/d2x.dep
4 changes: 4 additions & 0 deletions make/dirs.mk
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,7 @@ UTIL_OBJS=$(subst $(SRC_DIR),$(BUILD_DIR),$(UTIL_SRC:.cpp=.o))

LIBRARY_OBJS=$(BUILDER_OBJS) $(BLOCKS_OBJS) $(UTIL_OBJS)
LIBRARY=$(BUILD_DIR)/lib$(LIBRARY_NAME).a

D2X_DIR?=$(BASE_DIR)/deps/d2x
D2X_BUILD_DIR?=$(D2X_DIR)/build
D2X_DEPS=$(wildcard $(D2X_DIR)/src/*) $(wildcard $(D2X_DIR)/include/*) $(wildcard $(D2X_DIR)/runtime/*)
2 changes: 1 addition & 1 deletion make/format.mk
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ CHECK_CONFIG=0
endif

format:
clang-format -i -style=file $$(find -name "*.h" -o -name "*.cpp")
clang-format -i -style=file $$(find \( -name "*.h" -o -name "*.cpp" \) -a -not -path "./deps/*")
28 changes: 26 additions & 2 deletions make/setvars.mk
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,53 @@
RECOVER_VAR_NAMES ?= 0
TRACER_USE_LIBUNWIND ?= 0
DEBUG ?= 0
ENABLE_D2X ?= 0
EXTRA_CFLAGS?=

ifeq ($(ENABLE_D2X),1)
DEBUG=1
RECOVER_VAR_NAMES=1
endif

ifeq ($(RECOVER_VAR_NAMES),1)
ifneq ($(shell uname), Linux)
$(error RECOVER_VAR_NAMES only supported on Linux)
endif
DEBUG=1
endif

EXTRA_CFLAGS?=


DEPS_LIST=
LINKER_FLAGS=

ifeq ($(ENABLE_D2X),1)
LINKER_FLAGS+=-Wl,--start-group -L $(D2X_BUILD_DIR) -ld2x
DEPS_LIST+=$(BUILD_DIR)/d2x.dep
endif

# Create CFLAGS, LINKER_FLAGS, CFLAGS_INTERNAL and INCLUDE_FLAGS based on config
CFLAGS_INTERNAL=-std=c++11 -Wall -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -Wmissing-declarations
CFLAGS_INTERNAL+=-Woverloaded-virtual -Wno-deprecated -Wdelete-non-virtual-dtor -Werror -Wno-vla -pedantic-errors
CFLAGS=
LINKER_FLAGS=-L$(BUILD_DIR)/ -l$(LIBRARY_NAME)
LINKER_FLAGS+=-L$(BUILD_DIR)/ -l$(LIBRARY_NAME)
INCLUDE_FLAGS=-I$(INCLUDE_DIR) -I$(BUILD_DIR)/gen_headers/

ifeq ($(ENABLE_D2X),1)
LINKER_FLAGS+=-Wl,--end-group
CFLAGS_INTERNAL+=-DENABLE_D2X
INCLUDE_FLAGS+=-I $(D2X_DIR)/include
endif

ifeq ($(DEBUG),1)
CFLAGS+=-g -gdwarf-4
LINKER_FLAGS+=-g -gdwarf-4
else
CFLAGS_INTERNAL+=-O3
endif



ifeq ($(TRACER_USE_LIBUNWIND),1)
CFLAGS_INTERNAL+=-DTRACER_USE_LIBUNWIND
endif
Expand Down
Loading

0 comments on commit 40013df

Please sign in to comment.