From 4b1f9e2cb436e74ce6084dbc35df5f052cb701bf Mon Sep 17 00:00:00 2001 From: David Phillips Date: Sun, 4 Aug 2019 14:21:05 +1200 Subject: Wrap tests in valgrind, clean up memory leaks --- Makefile | 2 +- assembler.c | 5 ++++ disassembler.c | 4 ++++ lex.c | 18 ++++++++++++++ lex.h | 1 + parse.c | 16 +++++++++++++ parse.h | 1 + test/emul/run-emul.sh | 42 +++++++++++++++++---------------- test/full-pipeline/run-full-pipeline.sh | 7 +++--- test/valgrind.sh | 2 ++ 10 files changed, 74 insertions(+), 24 deletions(-) create mode 100644 test/valgrind.sh diff --git a/Makefile b/Makefile index 99d04ae..e3cb8e5 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ EXECUTABLES = assembler disassembler emulator asmcat bincat ASM_OBJECTS = assembler.o lex.o parse.o output/output_bin.o util.o -DISASM_OBJECTS = disassembler.o input/input_bin.o output/output_asm.o util.o +DISASM_OBJECTS = disassembler.o input/input_bin.o output/output_asm.o parse.o util.o EMUL_OBJECTS = input/input_bin.o util.o ASMCAT_OBJECTS = asmcat.o lex.o parse.o output/output_asm.o util.o BINCAT_OBJECTS = bincat.o input/input_bin.o output/output_bin.o util.o diff --git a/assembler.c b/assembler.c index 7ae699d..bd94c33 100644 --- a/assembler.c +++ b/assembler.c @@ -1,4 +1,5 @@ #include +#include #include #include @@ -63,6 +64,7 @@ int main(int argc, char **argv) if ((tokens = lex(path_in, fin, &tok_count)) == NULL) return error_ret; + fclose(fin); debug("Lexed.\n"); /* FIXME package these things into `tok_result`, `parse_result` etc */ @@ -82,6 +84,9 @@ int main(int argc, char **argv) if ((ret = output_bin(fout, labels, labels_count, insts, insts_count))) return error_ret && ret; + parse_free(insts, insts_count, labels, labels_count); + lex_free(tokens, tok_count); + fclose(fout); debug("Output.\n"); return 0; diff --git a/disassembler.c b/disassembler.c index 8da5a38..26f0b79 100644 --- a/disassembler.c +++ b/disassembler.c @@ -64,8 +64,12 @@ int main(int argc, char **argv) if ((ret = input_bin(fin, &insts, &insts_count))) return error_ret && ret; + fclose(fin); + if ((ret = output_asm(fout, labels, labels_count, insts, insts_count))) return error_ret && ret; + parse_free(insts, insts_count, NULL, 0); + fclose(fout); return 0; } diff --git a/lex.c b/lex.c index 949425e..6ed8007 100644 --- a/lex.c +++ b/lex.c @@ -380,6 +380,24 @@ int lex_line(void) { return 0; } +void lex_free_tok(struct token t) +{ + if (t.s_val) + free(t.s_val); + +} + +void lex_free(struct token *ts, size_t t_count) +{ + size_t i = 0; + + for (i = 0; i < t_count; i++) { + lex_free_tok(ts[i]); + } + + free(ts); +} + struct token* lex(const char *filename_local, FILE *fin, size_t *len) { filename = filename_local; diff --git a/lex.h b/lex.h index a14528f..908d23e 100644 --- a/lex.h +++ b/lex.h @@ -26,5 +26,6 @@ struct token { }; struct token* lex(const char *filename_local, FILE *fin, size_t *len); +void lex_free(struct token *ts, size_t t_count); #endif /* LEX_H */ diff --git a/parse.c b/parse.c index 45758c9..2bfc7da 100644 --- a/parse.c +++ b/parse.c @@ -471,6 +471,22 @@ int parse_instruction(void) return 1; } +void parse_free_l(struct label l) +{ + free(l.name); +} + +void parse_free(struct instruction *is, size_t i_count, struct label *ls, size_t l_count) +{ + size_t i = 0; + + for (i = 0; i < l_count; i++) { + parse_free_l(ls[i]); + } + free(ls); + free(is); +} + int parse(const char *filename_local, FILE* fd_local, struct label **labels_local, size_t *labels_count_local, struct token *tokens_local, size_t tokens_count_local, struct instruction **instructions, size_t *instructions_count) { int ret = 0; diff --git a/parse.h b/parse.h index 5feb420..d5fc466 100644 --- a/parse.h +++ b/parse.h @@ -61,5 +61,6 @@ struct instruction { }; int parse(const char *filename_local, FILE *fd, struct label **labels_local, size_t *labels_count_local, struct token *tokens, size_t tokens_count, struct instruction **instructions, size_t *instructions_count); +void parse_free(struct instruction *is, size_t i_count, struct label *ls, size_t l_count); #endif /* PARSE_H */ diff --git a/test/emul/run-emul.sh b/test/emul/run-emul.sh index 496f13d..2db56f3 100755 --- a/test/emul/run-emul.sh +++ b/test/emul/run-emul.sh @@ -23,6 +23,7 @@ clean() { WORK=$(mktemp -d) pushd $(dirname "$0") >/dev/null +source ../valgrind.sh export ASM="$PWD/../../assembler" export EMUL="$PWD/../../emulator" has_failure=0 @@ -36,26 +37,27 @@ for asmfile in *.asm ; do continue fi - "$EMUL" "$binfile" > "$outfile" - - # Each postcondition line must hold true, and forms a separate test to - # help track down failures - (echo '; POST $0 = 0' ; - echo '; POST $H = 0xFFFF' ; - grep '^;\s\+POST\s\+' "$asmfile" ) | while read line ; do - reg=$(awk -F= '{print $1}' <<< "$line" | awk '{print $(NF)}') - val=$(awk -F= '{print $2}' <<< "$line"| awk '{print $1}') - subtest="${asmfile}:${reg}" - # Scrape output of emulator for register value - actual=$(grep "$reg" "$outfile" | awk '{print $2}') - if [[ "$actual" -eq "$val" ]]; then - pass "$subtest" - else - fail "$subtest" "postcondition (expect $val, got $actual)" - has_failure=1 - fi - done - + if "$VALGRIND" $VALGRIND_OPTS "$EMUL" "$binfile" > "$outfile" ; then + # Each postcondition line must hold true, and forms a separate test to + # help track down failures + (echo '; POST $0 = 0' ; + echo '; POST $H = 0xFFFF' ; + grep '^;\s\+POST\s\+' "$asmfile" ) | while read line ; do + reg=$(awk -F= '{print $1}' <<< "$line" | awk '{print $(NF)}') + val=$(awk -F= '{print $2}' <<< "$line"| awk '{print $1}') + subtest="${asmfile}:${reg}" + # Scrape output of emulator for register value + actual=$(grep "$reg" "$outfile" | awk '{print $2}') + if [[ "$actual" -eq "$val" ]]; then + pass "$subtest" + else + fail "$subtest" "postcondition (expect $val, got $actual)" + has_failure=1 + fi + done + else + fail "$asmfile" "non-zero exit code" + fi done popd >/dev/null diff --git a/test/full-pipeline/run-full-pipeline.sh b/test/full-pipeline/run-full-pipeline.sh index aeb7c4f..cfa149f 100755 --- a/test/full-pipeline/run-full-pipeline.sh +++ b/test/full-pipeline/run-full-pipeline.sh @@ -29,6 +29,7 @@ else fi WORK=$(mktemp -d) pushd $(dirname "$0") >/dev/null +source ../valgrind.sh export ASM="$PWD/../../assembler" export DISASM="$PWD/../../disassembler" has_failure=0 @@ -39,17 +40,17 @@ for first_stage_asm in *.asm ; do second_stage_bin="$WORK/${first_stage_asm}-second_stage.bin" # Assemble test code - if ! "$ASM" "$first_stage_asm" "$first_stage_bin" ; then + if ! "$VALGRIND" $VALGRIND_OPTS "$ASM" "$first_stage_asm" "$first_stage_bin" ; then fail "$first_stage_asm" "first stage assembly failed" continue fi # Disassemble test code and re-assemble that disassembly - if ! "$DISASM" "$first_stage_bin" "$second_stage_asm" ; then + if ! "$VALGRIND" $VALGRIND_OPTS "$DISASM" "$first_stage_bin" "$second_stage_asm" ; then fail "$first_stage_asm" "first stage disassembly failed" continue fi - if ! "$ASM" "$second_stage_asm" "$second_stage_bin" ; then + if ! "$VALGRIND" $VALGRIND_OPTS "$ASM" "$second_stage_asm" "$second_stage_bin" ; then fail "$first_stage_asm" "second stage assembly failed" continue fi diff --git a/test/valgrind.sh b/test/valgrind.sh new file mode 100644 index 0000000..9c230d4 --- /dev/null +++ b/test/valgrind.sh @@ -0,0 +1,2 @@ +VALGRIND=valgrind +VALGRIND_OPTS="-q --error-exitcode=1 --leak-check=full --show-reachable=yes" -- cgit v1.1