Browse Source

Tests!

master
A.Olokhtonov 3 years ago
parent
commit
9ce5a31681
  1. 33
      build.sh
  2. 21
      project.4coder
  3. 2
      res/002-compilation-units.c
  4. 7
      res/Makefile
  5. BIN
      res/traceme
  6. 2
      src/Makefile
  7. 2
      src/command.c
  8. 2
      src/main.c
  9. 8
      src/util.c
  10. 211
      test/test_main.c

33
build.sh

@ -0,0 +1,33 @@ @@ -0,0 +1,33 @@
#!/bin/bash
set -e
set -x
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
pushd $SCRIPT_DIR
if [[ $# = 0 ]]; then
pushd src
mkdir -p ../build
gcc main.c -g -O0 -o ../build/trace -Wall -Wextra -Wno-unused-variable -Wno-unused-function -Wno-switch # -fsanitize=address
popd
elif [[ $1 = "examples" ]]; then
pushd res
gcc -g -o 001-simple 001-simple.c
gcc -g -o 002-compilation-units 002-compilation-units.c 002-compilation-units-impl.c
gcc -g -o 003-recursion 003-recursion.c
gcc -g -o 004-scoped-variables 004-scoped-variables.c
gcc -g -o 005-base-types 005-base-types.c
gcc -g -o 006-composite-types 006-composite-types.c
popd
elif [[ $1 = "tests" ]]; then
pushd test/
gcc test_main.c -g -o ../build/test -Wall -Wextra -Wno-unused-function -Wno-unused-variable
popd
elif [[ $1 = "clean" ]]; then
rm build/*
else
echo "No such target '$1'"
fi
popd

21
project.4coder

@ -11,6 +11,7 @@ patterns = { @@ -11,6 +11,7 @@ patterns = {
blacklist_patterns = {
".*",
"res",
"test",
"lib",
"build/*"
};
@ -30,8 +31,26 @@ command_list = { @@ -30,8 +31,26 @@ command_list = {
.footer_panel = false,
.save_dirty_files = true,
.cursor_at_end = true,
.cmd = {{ "cd src && make debug && cd ..", .os = "linux" }},
.cmd = {{ "./build.sh", .os = "linux" }},
},
{
.name = "build examples",
.out = "*compilation*",
.footer_panel = false,
.save_dirty_files = true,
.cursor_at_end = true,
.cmd = {{ "./build.sh examples", .os = "linux" }},
},
{
.name = "build tests",
.out = "*compilation*",
.footer_panel = false,
.save_dirty_files = true,
.cursor_at_end = true,
.cmd = {{ "./build.sh tests", .os = "linux" }},
},
};
fkey_command[1] = "build debug";
fkey_command[2] = "build examples";
fkey_command[3] = "build tests";

2
res/002-compilation-units.c

@ -5,5 +5,5 @@ main(void) @@ -5,5 +5,5 @@ main(void)
{
int a = 3;
int b = foo(a);
return(b);
return(0);
}

7
res/Makefile

@ -1,7 +0,0 @@ @@ -1,7 +0,0 @@
all:
gcc -g -o 001-simple 001-simple.c
gcc -g -o 002-compilation-units 002-compilation-units.c 002-compilation-units-impl.c
gcc -g -o 003-recursion 003-recursion.c
gcc -g -o 004-scoped-variables 004-scoped-variables.c
gcc -g -o 005-base-types 005-base-types.c
gcc -g -o 006-composite-types 006-composite-types.c

BIN
res/traceme

Binary file not shown.

2
src/Makefile

@ -1,2 +0,0 @@ @@ -1,2 +0,0 @@
debug:
gcc main.c -g -O0 -o ../build/trace -Wall -Wextra -Wno-unused-variable -Wno-unused-function -Wno-switch # -fsanitize=address

2
src/command.c

@ -155,6 +155,8 @@ command_print(struct mi_process proc, char *name, int name_length) @@ -155,6 +155,8 @@ command_print(struct mi_process proc, char *name, int name_length)
u64 address = cfa + variable->location;
u64 raw_value = ptrace(PTRACE_PEEKDATA, proc.pid, address, NULL);
printf("\"%s\", %ld\n", type.name, variable->location);
u8 raw_value1;
u16 raw_value2;
u32 raw_value4;

2
src/main.c

@ -21,8 +21,6 @@ main(int argc, char *argv[]) @@ -21,8 +21,6 @@ main(int argc, char *argv[])
char *command = malloc(max_command_length + 1);
char *last_command = malloc(max_command_length + 1);
process.base_address = 0x555555554000UL; // get_executable_base_address(file, proc.pid);
parse_debug_info(process.elf, &process.debug);
parse_debug_line(process.elf, &process.debug);

8
src/util.c

@ -202,7 +202,7 @@ print_sourcepoint(struct mi_process proc, int comp_unit, struct mi_sourcepoint * @@ -202,7 +202,7 @@ print_sourcepoint(struct mi_process proc, int comp_unit, struct mi_sourcepoint *
}
printf("%.*s\n", len - start, source + i + start);
printf("%d:%d] %.*s\n", sp->line, sp->column, len - start, source + i + start);
return;
}
@ -236,11 +236,17 @@ process_create(char *path) @@ -236,11 +236,17 @@ process_create(char *path)
}
}
// TODO: readup man (2) ptrace: how to wait for execve
//waitpid(pid, 0, 0);
//ptrace(PTRACE_CONT, pid, 0, 0);
//waitpid(pid, 0, 0);
struct mi_buffer file = read_file_mmap(path);
result.elf = file.data;
result.elf_size = file.size;
result.pid = pid;
result.base_address = 0x555555554000UL; // get_executable_base_address(file, proc.pid);
return(result);
}

211
test/test_main.c

@ -0,0 +1,211 @@ @@ -0,0 +1,211 @@
#include "../src/common.h"
#include "../src/dwarf.c"
#include "../src/eh_frame.c"
#include "../src/util.c"
#include "../src/command.c"
#define DO_TEST(title, call) do { \
int rt = call; \
if (rt == 0) { \
fprintf(stderr, "Test '%s' \033[1m\033[32msuccess\033[0m...\n", title); \
} else { \
fprintf(stderr, "Test '%s' \033[1m\033[31mfail\033[0m\n", title); \
exit(1); \
} \
} while(0)
static int
test_start(char *path)
{
struct mi_process proc = process_create(path);
waitpid(proc.pid, 0, 0);
parse_debug_info(proc.elf, &proc.debug);
proc.main_address = get_address_of_subroutine(proc, "main");
command_start(proc);
struct mi_registers regs = get_process_registers(proc);
int result = 1;
if (proc.main_address == regs.rip - proc.base_address) {
result = 0;
}
command_kill(proc);
waitpid(proc.pid, 0, 0);
return(result);
}
static int
test_regs(char *path)
{
struct mi_process proc = process_create(path);
waitpid(proc.pid, 0, 0);
parse_debug_info(proc.elf, &proc.debug);
proc.main_address = get_address_of_subroutine(proc, "main");
command_start(proc);
struct mi_registers regs = get_process_registers(proc);
int result = 1;
if (regs.rbp > 0 && regs.rsp > 0 && regs.rip > 0) {
result = 0;
}
command_kill(proc);
waitpid(proc.pid, 0, 0);
return(result);
}
static int
test_step(char *path, int steps, u64 pc)
{
struct mi_process proc = process_create(path);
waitpid(proc.pid, 0, 0);
parse_debug_info(proc.elf, &proc.debug);
parse_debug_line(proc.elf, &proc.debug);
proc.main_address = get_address_of_subroutine(proc, "main");
command_start(proc);
for (int i = 0; i < steps; ++i) {
command_step(proc);
}
struct mi_registers regs = get_process_registers(proc);
int result = 1;
if ((regs.rip - proc.base_address) == pc) {
result = 0;
}
command_kill(proc);
waitpid(proc.pid, 0, 0);
return(result);
}
static int
test_next(char *path, int nexts, u64 pc)
{
struct mi_process proc = process_create(path);
waitpid(proc.pid, 0, 0);
parse_debug_info(proc.elf, &proc.debug);
parse_debug_line(proc.elf, &proc.debug);
proc.main_address = get_address_of_subroutine(proc, "main");
command_start(proc);
for (int i = 0; i < nexts; ++i) {
command_next(proc);
}
struct mi_registers regs = get_process_registers(proc);
int result = 1;
if ((regs.rip - proc.base_address) == pc) {
result = 0;
}
command_kill(proc);
waitpid(proc.pid, 0, 0);
return(result);
}
static int
test_list(char *path, int steps, int line, int column)
{
struct mi_process proc = process_create(path);
waitpid(proc.pid, 0, 0);
parse_debug_info(proc.elf, &proc.debug);
parse_debug_line(proc.elf, &proc.debug);
proc.main_address = get_address_of_subroutine(proc, "main");
command_start(proc);
for (int i = 0; i < steps; ++i) {
command_step(proc);
}
int comp_unit;
struct mi_registers regs = get_process_registers(proc);
struct mi_sourcepoint *sp = pc_to_sourcepoint(proc, regs.rip - proc.base_address, &comp_unit);
int result = 1;
if (sp->line == line && sp->column == column) {
result = 0;
}
command_kill(proc);
waitpid(proc.pid, 0, 0);
return(result);
}
static int
test_print(char *path, int steps, char *name, char *type, int location)
{
struct mi_process proc = process_create(path);
waitpid(proc.pid, 0, 0);
parse_debug_info(proc.elf, &proc.debug);
parse_debug_line(proc.elf, &proc.debug);
proc.main_address = get_address_of_subroutine(proc, "main");
command_start(proc);
for (int i = 0; i < steps; ++i) {
command_step(proc);
}
struct mi_registers regs = get_process_registers(proc);
u64 pc = regs.rip - proc.base_address;
u64 cfa = get_cfa_at_pc(proc, pc);
struct mi_variable *variable = get_variable(proc, name, strlen(name), pc);
struct mi_type real_type = proc.debug.types[variable->type];
int result = 1;
int type_length = strlen(type);
if (0 == strncmp(type, real_type.name, type_length) && variable->location == location) {
result = 0;
}
command_kill(proc);
waitpid(proc.pid, 0, 0);
return(result);
}
int
main(void)
{
DO_TEST("start 001-simple", test_start("res/001-simple"));
DO_TEST("start 002-compilation-units", test_start("res/002-compilation-units"));
DO_TEST("start 003-recursion", test_start("res/003-recursion"));
DO_TEST("start 004-scoped-variables", test_start("res/004-scoped-variables"));
DO_TEST("start 005-base-types", test_start("res/005-base-types"));
DO_TEST("start 006-composite-types", test_start("res/006-composite-types"));
DO_TEST("regs 001-simple", test_regs("res/001-simple"));
DO_TEST("regs 002-compilation-units", test_regs("res/002-compilation-units"));
DO_TEST("regs 003-recursion", test_regs("res/003-recursion"));
DO_TEST("regs 004-scoped-variables", test_regs("res/004-scoped-variables"));
DO_TEST("regs 005-base-types", test_regs("res/005-base-types"));
DO_TEST("regs 006-composite-types", test_regs("res/006-composite-types"));
DO_TEST("step 001-simple", test_step("res/001-simple", 4, 0x1166));
DO_TEST("step 002-compilation-units", test_step("res/002-compilation-units", 4, 0x114f));
DO_TEST("step 003-recursion", test_step("res/003-recursion", 9, 0x1130));
DO_TEST("step 004-scoped-variables", test_step("res/004-scoped-variables", 7, 0x1145));
DO_TEST("step 005-base-types", test_step("res/005-base-types", 3, 0x113e));
DO_TEST("step 006-composite-types", test_step("res/006-composite-types", 5, 0x114c));
DO_TEST("next 001-simple", test_next("res/001-simple", 4, 0x1166));
DO_TEST("next 002-compilation-units", test_next("res/002-compilation-units", 4, 0x1146));
DO_TEST("next 003-recursion", test_next("res/003-recursion", 2, 0x116b));
DO_TEST("next 004-scoped-variables", test_next("res/004-scoped-variables", 4, 0x11a3));
DO_TEST("next 005-base-types", test_next("res/005-base-types", 3, 0x113e));
DO_TEST("next 006-composite-types", test_next("res/006-composite-types", 5, 0x114c));
DO_TEST("list 001-simple", test_list("res/001-simple", 4, 12, 20));
DO_TEST("list 002-compilation-units", test_list("res/002-compilation-units", 4, 5, 6));
DO_TEST("list 003-recursion", test_list("res/003-recursion", 9, 4, 5));
DO_TEST("list 004-scoped-variables", test_list("res/004-scoped-variables", 7, 15, 6));
DO_TEST("list 005-base-types", test_list("res/005-base-types", 3, 6, 7));
DO_TEST("list 006-composite-types", test_list("res/006-composite-types", 5, 18, 14));
DO_TEST("print 001-simple", test_print("res/001-simple", 4, "i", "int", -28));
DO_TEST("print 002-compilation-units", test_print("res/002-compilation-units", 5, "sq", "int", -20));
DO_TEST("print 003-recursion", test_print("res/003-recursion", 28, "result", "int", -20));
DO_TEST("print 004-scoped-variables", test_print("res/004-scoped-variables", 9, "b_f2", "int", -24));
DO_TEST("print 005-base-types long", test_print("res/005-base-types", 5, "var_unsigned_long", "long unsigned int", -40));
DO_TEST("print 005-base-types char", test_print("res/005-base-types", 4, "var_char", "char", -41));
DO_TEST("print 005-base-types float", test_print("res/005-base-types", 8, "var_float", "float", -48));
DO_TEST("print 005-base-types double", test_print("res/005-base-types", 9, "var_double", "double", -56));
fprintf(stderr, "\033[1m\033[32mAll tests succeeded!\033[0m\n");
return(0);
}
Loading…
Cancel
Save