Skip to content

Commit

Permalink
Add buffering for json output.
Browse files Browse the repository at this point in the history
The buffering is done via a macro to not have to use
vprintf family function to not expose va_list.
The buffer is of 4 memory pages and the maximum write in 1 time
is 1 memory pages. If a write is longer than a memory page dynStruct
will not segfault but the a part of the output will be lost.
But this is unlikely to happen.
  • Loading branch information
ampotos committed Sep 26, 2016
1 parent 3099f78 commit c30affa
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 41 deletions.
21 changes: 21 additions & 0 deletions includes/out_json.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,28 @@
#define OUT_JSON_H_

#include "dr_api.h"
#include "utils.h"

// This value are arbitrary, they may need to be adapt in specific cases
#define GLOBAL_BUF_SIZE PAGE_SIZE * 4
#define TMP_BUF_SIZE PAGE_SIZE

extern char *global_buf;
extern char *tmp_buf;
extern int global_idx;
extern int len_tmp;

//here macro is used instead of a function to avoid exposing va_list
#define DS_PRINTF(...) if (!global_buf || !tmp_buf) \
init_buffering(); \
len_tmp = dr_snprintf(tmp_buf, PAGE_SIZE, __VA_ARGS__); \
if (global_idx + len_tmp + 1 > PAGE_SIZE * 4) \
{ \
dr_write_file(args->file_out, global_buf, global_idx); \
global_idx = 0; \
} \
ds_memcpy(global_buf + global_idx, tmp_buf, len_tmp); \
global_idx += len_tmp;
void write_json(void);
void flush_old_block(void);

Expand Down
1 change: 1 addition & 0 deletions includes/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ size_t ds_strlen(const char *str);
int ds_strncmp(const char *str1, const char *str2, size_t size);
int ds_strcmp(const char *str1, const char *str2);
void ds_memset(void *ptr, int c, size_t size);
void ds_memcpy(void *dest, void *src, size_t size);
char *ds_strncpy(char *dest, const char *src, size_t size);

#endif
Expand Down
94 changes: 53 additions & 41 deletions src/out_json.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,55 @@
#include "../includes/tree.h"
#include "../includes/args.h"
#include "../includes/block_utils.h"
#include "../includes/out_json.h"

#define NULL_STR(s) ((s) ? (s) : "")

char *global_buf = NULL;
char *tmp_buf = NULL;
int global_idx = 0;
int len_tmp = 0;

void init_buffering()
{
DR_ASSERT((global_buf = dr_custom_alloc(NULL, DR_ALLOC_NON_HEAP | DR_ALLOC_NON_DR, GLOBAL_BUF_SIZE,
DR_MEMPROT_WRITE | DR_MEMPROT_READ , NULL)));
DR_ASSERT((tmp_buf = dr_custom_alloc(NULL, DR_ALLOC_NON_HEAP | DR_ALLOC_NON_DR, TMP_BUF_SIZE,
DR_MEMPROT_WRITE | DR_MEMPROT_READ , NULL)));
}

void stop_buffering()
{
dr_write_file(args->file_out, global_buf, global_idx);
dr_custom_free(NULL, DR_ALLOC_NON_HEAP | DR_ALLOC_NON_DR, global_buf, GLOBAL_BUF_SIZE);
dr_custom_free(NULL, DR_ALLOC_NON_HEAP | DR_ALLOC_NON_DR, tmp_buf, TMP_BUF_SIZE);
}

void print_orig_json(orig_t *orig)
{
orig_t *tmp;

while (orig)
{
dr_fprintf(args->file_out, "{\"size_access\":%lu, \"nb_access\":%lu, ",
DS_PRINTF("{\"size_access\":%lu, \"nb_access\":%lu, ",
orig->size, orig->nb_hit);
dr_fprintf(args->file_out,
DS_PRINTF(
"\"pc\":%lu, \"func_pc\":%lu, \"func_sym\":\"%s\", ",
orig->addr, orig->start_func_addr,
NULL_STR(orig->start_func_sym));
dr_fprintf(args->file_out, "\"func_module\":\"%s\", \"opcode\":\"",
DS_PRINTF("\"func_module\":\"%s\", \"opcode\":\"",
NULL_STR(orig->module_name));
for (unsigned int size = 0; size < orig->instr_size; size++)
dr_fprintf(args->file_out, "%02x", orig->raw_instr[size]);
dr_fprintf(args->file_out, "\", \"ctx_addr\":%lu, \"ctx_opcode\":\"",
{
DS_PRINTF("%02x", orig->raw_instr[size]);
}
DS_PRINTF("\", \"ctx_addr\":%lu, \"ctx_opcode\":\"",
orig->ctx_addr);
for (unsigned int size = 0; size < orig->ctx_instr_size; size++)
dr_fprintf(args->file_out, "%02x", orig->raw_ctx_instr[size]);
dr_fprintf(args->file_out, "\"}, ");
{
DS_PRINTF("%02x", orig->raw_ctx_instr[size]);
}
DS_PRINTF("\"}, ");

tmp = orig->next;
orig = tmp;
Expand All @@ -35,78 +60,65 @@ void print_orig_json(orig_t *orig)

void print_access_json(access_t *access)
{
dr_fprintf(args->file_out, "{\"offset\":%lu, \"total_access\" : %lu, ",
DS_PRINTF("{\"offset\":%lu, \"total_access\" : %lu, ",
access->offset, access->total_hits);

dr_fprintf(args->file_out, "\"details\":[");
DS_PRINTF("\"details\":[");
clean_tree(&(access->origs), (void (*)(void *))print_orig_json, false);
dr_fprintf(args->file_out, "{}]}, ");
DS_PRINTF("{}]}, ");
}

void print_block_json(malloc_t *block)
{
dr_fprintf(args->file_out,
"{\"start\":%lu, \"end\":%lu, \"size\":%lu, ",
DS_PRINTF("{\"start\":%lu, \"end\":%lu, \"size\":%lu, ",
block->start, block->end, block->size);

dr_fprintf(args->file_out,
"\"free\":%d, \"alloc_by_realloc\":%d, \"free_by_realloc\":%d, ",
DS_PRINTF("\"free\":%d, \"alloc_by_realloc\":%d, \"free_by_realloc\":%d, ",
(block->flag & FREE) != 0, (block->flag & ALLOC_BY_REALLOC) != 0,
(block->flag & FREE_BY_REALLOC) != 0);

dr_fprintf(args->file_out,
"\"alloc_pc\":%lu, \"alloc_func\":%lu, \"alloc_sym\":\"%s\", ",
DS_PRINTF("\"alloc_pc\":%lu, \"alloc_func\":%lu, \"alloc_sym\":\"%s\", ",
block->alloc_pc, block->alloc_func_pc,
NULL_STR(block->alloc_func_sym));
dr_fprintf(args->file_out,
"\"alloc_module\":\"%s\", ", NULL_STR(block->alloc_module_name));
DS_PRINTF("\"alloc_module\":\"%s\", ", NULL_STR(block->alloc_module_name));

dr_fprintf(args->file_out,
"\"free_pc\":%lu, \"free_func\":%lu, \"free_sym\":\"%s\", ",
DS_PRINTF("\"free_pc\":%lu, \"free_func\":%lu, \"free_sym\":\"%s\", ",
block->free_pc, block->free_func_pc,
NULL_STR(block->free_func_sym));
dr_fprintf(args->file_out,
"\"free_module\":\"%s\", ", NULL_STR(block->free_module_name));
DS_PRINTF("\"free_module\":\"%s\", ", NULL_STR(block->free_module_name));

dr_fprintf(args->file_out, "\"read_access\" : [");
DS_PRINTF("\"read_access\" : [");
clean_tree(&(block->read), (void (*)(void*))print_access_json, false);
dr_fprintf(args->file_out, "{}], ");
DS_PRINTF("{}], ");

dr_fprintf(args->file_out, "\"write_access\" : [");
DS_PRINTF("\"write_access\" : [");
clean_tree(&(block->write), (void (*)(void*))print_access_json, false);
dr_fprintf(args->file_out, "{}]");
DS_PRINTF("{}]");

dr_fprintf(args->file_out, "}, ");
DS_PRINTF("}, ");

custom_free_pages(block);
dr_custom_free(NULL, 0, block, sizeof(*block));
}

void write_json(void)
void flush_old_block(void)
{
malloc_t *tmp;

while (old_blocks)
{
tmp = old_blocks->next;
print_block_json(old_blocks);
old_blocks = tmp;
}
clean_tree(&active_blocks, (void (*)(void*))print_block_json, false);

dr_fprintf(args->file_out, "{}]}");
}

void flush_old_block(void)
void write_json(void)
{
malloc_t *tmp;

while (old_blocks)
{
tmp = old_blocks->next;
print_block_json(old_blocks);
old_blocks = tmp;
}
flush_old_block();
clean_tree(&active_blocks, (void (*)(void*))print_block_json, false);

dr_flush_file(args->file_out);
DS_PRINTF("{}]}");
stop_buffering();
}
7 changes: 7 additions & 0 deletions src/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,13 @@ void ds_memset(void *ptr, int c, size_t size)
*((char *)ptr) = (char)c;
}

void ds_memcpy(void *dest, void *src, size_t size)
{
while (--size > 0)
((char *)dest)[size] = ((char*)src)[size];
*((char *)dest) = *((char *)src);
}

char *ds_strncpy(char *dest, const char *src, size_t size)
{
for (size_t ct = 0; ct < size; ct++)
Expand Down

0 comments on commit c30affa

Please sign in to comment.