Skip to content

Commit

Permalink
some cleanup and interfaces for limiting what is traced depending on …
Browse files Browse the repository at this point in the history
…time frames etc
  • Loading branch information
matthewfl committed Aug 2, 2016
1 parent 10aa760 commit 0e5751b
Show file tree
Hide file tree
Showing 9 changed files with 474 additions and 32 deletions.
198 changes: 198 additions & 0 deletions crash.org

Large diffs are not rendered by default.

28 changes: 25 additions & 3 deletions src/config.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
#ifndef REDMAGIC_CONFIG_H_
#define REDMAGIC_CONFIG_H_

// configure the system to perform more traces to attempt to debug
#define CONF_DEBUG_BUILD

#ifndef CONF_DEBUG_BUILD
# define CONF_RELEASE_BUILD
# define CONF_BUILD_TOGGLE(debug, release) release
#else
# define CONF_BUILD_TOGGLE(debug, release) debug
#endif


// the number of loops that are require to occure before it traces a loop
#define CONF_NUMBER_OF_JUMPS_BEFORE_TRACE 10
#define CONF_NUMBER_OF_JUMPS_BEFORE_TRACE CONF_BUILD_TOGGLE(10, 150)

// redmagic will attempt inline forward jumps which is useful in cases like: `if(a || b || c...)` where many conditional jumps
// will merge to the same point, but it may require back tracking in a lot of cases which may be slower
Expand All @@ -15,14 +25,26 @@
#define CONF_ATTEMPT_BACKWARDS_JUMP_INLINE

// makes it print all the instructions processed and extra info
#define CONF_VERBOSE
#ifdef CONF_DEBUG_BUILD
# define CONF_VERBOSE
#endif

// support aborting the system after some fixed number of instruction have been processed, see tools/bisect for debugging with this
#define CONF_GLOBAL_ABORT
#ifdef CONF_DEBUG_BUILD
# define CONF_GLOBAL_ABORT
#endif


// somehow python is not hitting the fellthrough trace for some traces that it starts
// unable to determine where it should actually be performing this, so we are just makeing the end of the branchable frame
// close out any traces that were created in this frame
#define CONF_ALLOW_UNCLOSED_TRACES


// using timers in addition to number of times it loops to determine what to trace
#define CONF_USE_TIMERS
#define CONF_TIMER_DELAY_MS CONF_BUILD_TOGGLE(0, 5000)

#define CONF_ESTIMATE_INSTRUCTIONS

#endif // REDMAGIC_CONFIG_H_
73 changes: 73 additions & 0 deletions src/cpp_allocator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#ifndef REDMAGIC_CPP_ALLOCATOR_H_
#define REDMAGIC_CPP_ALLOCATOR_H_

#include <memory>

extern "C" void *__real_malloc(size_t size);
extern "C" void __real_free(void *ptr);

namespace redmagic {
template <typename T>
class RealMallocAllocator {
public:
typedef T value_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;

template <typename U>
struct rebind { typedef RealMallocAllocator<U> other; };

RealMallocAllocator() noexcept {}
template <typename U> RealMallocAllocator(const RealMallocAllocator<U> &x) noexcept {}
~RealMallocAllocator() noexcept {}

pointer address(reference x) const { return &x; }
const_pointer address(const_reference x) const {
return x;
}

pointer allocate(size_type n, const_pointer hint = 0) {
void* p = __real_malloc(n * sizeof(T));
if (!p)
throw std::bad_alloc();
return static_cast<pointer>(p);
}

void deallocate(pointer p, size_type n = 0) {
__real_free(p);
}

size_type max_size() const {
return static_cast<size_type>(-1) / sizeof(T);
}

template<typename U, typename... Args>
void construct(U* p, Args&&... x) {
new(p) U(std::forward<Args>(x)...);
}

template <typename U>
void destroy(U *p) { p->~U(); }

private:
void operator=(const RealMallocAllocator&);
};

template<typename A, typename B>
inline bool operator==(const RealMallocAllocator<A>&, const RealMallocAllocator<B>&) {
return true;
}

template<typename A, typename B>
inline bool operator!=(const RealMallocAllocator<A>&, const RealMallocAllocator<B>&) {
return false;
}

}


#endif // REDMAGIC_CPP_ALLOCATOR_H_
82 changes: 72 additions & 10 deletions src/jit_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,17 @@
#include <memory>
#include <assert.h>

#ifdef CONF_USER_TIMERS
#include <time.h>
#endif

// for write syscall
#include <unistd.h>

#include <udis86.h>

#include "cpp_allocator.h"

namespace redmagic {

class Manager;
Expand Down Expand Up @@ -99,11 +105,34 @@ namespace redmagic {
int sub_branches = 0;
int finish_traces = 0; // number of branched traces that reached the end (not merged blocked back)
uint64_t *trace_loop_counter = nullptr;

#ifdef CONF_USE_TIMERS
timespec first_observed_time;
#endif

#ifdef CONF_ESTIMATE_INSTRUCTIONS
// this may be wrong since it can be impacted by time that the processor has switched
// or the task has been interruptted
// TODO: maybe in the future use the amount of thread cpu time to estimate this
uint64_t avg_observed_instructions = 0;
#endif
};

std::unordered_map<void*, branch_info> branches;
std::unordered_map<
void*,
branch_info,
// should be the same as normal
std::hash<void*>,
std::equal_to<void*>,
RealMallocAllocator<std::pair<const void*, branch_info>>
> branches;
private:
std::unordered_set<void*> no_trace_methods;
std::unordered_set<
void*,
std::hash<void*>,
std::equal_to<void*>,
RealMallocAllocator<void*>
> no_trace_methods;

std::atomic<uint32_t> thread_id_counter;

Expand All @@ -124,6 +153,15 @@ namespace redmagic {
bool is_traced = false;
bool is_compiled = false;
int32_t frame_id = -1;


#ifdef CONF_ESTIMATE_INSTRUCTIONS
int num_backwards_loops = 0;
uint64_t instruction_cnt_at_start = 0;
uint64_t sub_frame_num_instructions = 0;
#endif

//void *d_ret = nullptr;
//bool did_abort = false;
};

Expand Down Expand Up @@ -261,13 +299,6 @@ namespace redmagic {
size_t external_trampolines_size = 0;

friend class SimpleCompiler;
// struct rebind_jumps {
// mem_loc_t buffer_offset;
// // suppose that this could disappear so might not be best idea to deallcate these and reallocate?
// CodeBuffer *origional_buffer;
// mem_loc_t origional_offset;
// };
// std::vector<rebind_jumps> jumps;

};

Expand All @@ -286,14 +317,45 @@ namespace redmagic {
::write(2, buffer, b);
}

/* assembly code to read the TSC */
#ifdef CONF_ESTIMATE_INSTRUCTIONS
// assembly code to read the TSC
static inline uint64_t RDTSC() {
unsigned int hi, lo;
__asm__ volatile("rdtsc" : "=a" (lo), "=d" (hi));
return ((uint64_t)hi << 32) | lo;
}

extern thread_local uint64_t last_thread_instructions;
extern thread_local uint64_t num_instructions_add;

static inline uint64_t instruction_cnt() {
// this value can go down when the processor resets or it changes between cores
uint64_t i = RDTSC();
if(i < last_thread_instructions)
num_instructions_add += last_thread_instructions - i;
last_thread_instructions = i;
return i + num_instructions_add;
}
#endif

#ifdef CONF_USE_TIMERS
static inline timespec time_delta(timespec start, timespec end) {
timespec temp;
if ((end.tv_nsec-start.tv_nsec)<0) {
temp.tv_sec = end.tv_sec-start.tv_sec-1;
temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
} else {
temp.tv_sec = end.tv_sec-start.tv_sec;
temp.tv_nsec = end.tv_nsec-start.tv_nsec;
}
return temp;
}

static inline uint64_t time_ms(timespec t) {
return t.tv_sec * 1000 + t.tv_nsec / 1000000;
}

#endif
}


Expand Down
Loading

0 comments on commit 0e5751b

Please sign in to comment.