Skip to content

Commit

Permalink
Merge pull request #1296 from criblio/feat-1279-coredumper-integration
Browse files Browse the repository at this point in the history
[#1279 3/4] Integrate coredumper with scope codebase
  • Loading branch information
jrcheli authored Jan 31, 2023
2 parents fee4081 + 1f9143c commit 3db6605
Show file tree
Hide file tree
Showing 15 changed files with 177 additions and 9 deletions.
3 changes: 3 additions & 0 deletions contrib/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,9 @@ build/libunwind/src/.libs/libunwind.a:
@mkdir build/coredumper
cd build/coredumper && autoreconf -fvi ../../coredumper && ../../coredumper/configure CFLAGS=-fPIC --disable-shared && $(MAKE)
objcopy --redefine-syms redefine_syms.lst build/coredumper/.libs/libcoredumper.a
if [ "aarch64" = "$(ARCH)" ]; then \
objcopy --redefine-sym getcontext=unw_scope_getcontext build/coredumper/.libs/libcoredumper.a; \
fi
@[ -z "$(CI)" ] || echo "::endgroup::"

build/musl/lib/libc.a:
Expand Down
1 change: 1 addition & 0 deletions contrib/libunwind/include/libunwind-common.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -317,5 +317,6 @@ extern int unw_get_proc_name_by_ip (unw_addr_space_t, unw_word_t, char *,
extern const char *unw_strerror (int);
extern int unw_backtrace (void **, int);
extern int unw_backtrace2 (void **, int, unw_context_t*, int);
extern int unw_scope_getcontext(unw_context_t *);

extern unw_addr_space_t unw_local_addr_space;
5 changes: 5 additions & 0 deletions contrib/libunwind/src/mi/backtrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,11 @@ unw_backtrace (void **buffer, int size)
return n;
}

int
unw_scope_getcontext(unw_context_t *uc) {
return unw_getcontext(uc);
}

int
unw_backtrace2 (void **buffer, int size, unw_context_t* uc2, int flag)
{
Expand Down
1 change: 1 addition & 0 deletions contrib/redefine_syms.lst
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ fwrite scopelibc_fwrite
gai_strerror scopelibc_gai_strerror
getaddrinfo scopelibc_getaddrinfo
getentropy scopelibc_getentropy
getpgrp scopelibc_getpgrp
gethostbyname scopelibc_gethostbyname
getnameinfo scopelibc_getnameinfo
getpagesize scopelibc_getpagesize
Expand Down
2 changes: 2 additions & 0 deletions libscope.map
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
_Ux86_64_*; # hides libunwind symbols
_ULx86_64_*; # hides libunwind symbols
_ULaarch64_*; # hides libunwind symbols
unw_scope_getcontext;
SCOPE_DlIteratePhdr;
ACCESS_*;
ADMISSIONS_*;
Expand Down Expand Up @@ -242,6 +243,7 @@
X9_*;
xor128_decrypt_n_pad;
xor128_encrypt_n_pad;
WriteCoreDump;
ZINT32_it;
ZINT64_it;
ZLONG_it;
Expand Down
5 changes: 3 additions & 2 deletions os/linux/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ LS_HPACK_AR=contrib/build/ls-hpack/libls-hpack.a
MUSL_AR=contrib/build/musl/lib/libc.a
UNWIND_AR=contrib/build/libunwind/src/.libs/libunwind.a
COREDUMPER_AR=contrib/build/coredumper/.libs/libcoredumper.a
TEST_AR=$(MUSL_AR) ${UNWIND_AR} $(YAML_AR) $(JSON_AR) $(PCRE2_AR) ${OPENSSL_AR} $(LS_HPACK_AR)
TEST_AR=$(MUSL_AR) ${COREDUMPER_AR} ${UNWIND_AR} $(YAML_AR) $(JSON_AR) $(PCRE2_AR) ${OPENSSL_AR} $(LS_HPACK_AR)
#TEST_LIB=contrib/build/cmocka/src/libcmocka.dylib
TEST_LIB=contrib/build/cmocka/src/libcmocka.so
TEST_LD_FLAGS=-Lcontrib/build/cmocka/src -lcmocka -ldl -lresolv -lrt -lpthread
Expand Down Expand Up @@ -99,8 +99,9 @@ $(SCOPEDYN): src/loader/scopedyn.c src/loader/loaderutils.c src/loader/libdir.c
libtest: $(LIBRARY_C_FILES) $(LIBRARY_TEST_C_FILES) $(YAML_AR) $(JSON_AR) $(TEST_LIB)
@echo "$${CI:+::group::}Building Library Tests"
$(CC) -c $(TEST_CFLAGS) $(LIBRARY_C_FILES) $(LIBRARY_INCLUDES) $(LIBRARY_TEST_C_FILES) $(INCLUDES) $(CMOCKA_INCLUDES) $(OS_C_FILES)
$(CC) $(TEST_CFLAGS) -o test/$(OS)/ipctest ipctest.o ipc.o ipc_resp.o cfgutils.o cfg.o mtc.o log.o evtformat.o ctl.o transport.o backoff.o mtcformat.o strset.o com.o scopestdlib.o dbg.o circbuf.o linklist.o fn.o utils.o os.o test.o report.o search.o httpagg.o state.o httpstate.o metriccapture.o plattime.o $(TEST_AR) $(TEST_LD_FLAGS) -Wl,--wrap=jsonConfigurationObject -Wl,--wrap=doAndReplaceConfig
$(CC) $(TEST_CFLAGS) -o test/$(OS)/vdsotest vdsotest.o scopestdlib.o dbg.o test.o $(TEST_AR) $(TEST_LD_FLAGS)
$(CC) $(TEST_CFLAGS) -o test/$(OS)/coredumptest coredumptest.o coredump.o scopestdlib.o dbg.o utils.o fn.o plattime.o os.o test.o $(TEST_AR) $(TEST_LD_FLAGS)
$(CC) $(TEST_CFLAGS) -o test/$(OS)/ipctest ipctest.o ipc.o ipc_resp.o cfgutils.o cfg.o mtc.o log.o evtformat.o ctl.o transport.o backoff.o mtcformat.o strset.o com.o scopestdlib.o dbg.o circbuf.o linklist.o fn.o utils.o os.o test.o report.o search.o httpagg.o state.o httpstate.o metriccapture.o plattime.o $(TEST_AR) $(TEST_LD_FLAGS) -Wl,--wrap=jsonConfigurationObject -Wl,--wrap=doAndReplaceConfig
$(CC) $(TEST_CFLAGS) -o test/$(OS)/strsettest strsettest.o strset.o scopestdlib.o dbg.o test.o $(TEST_AR) $(TEST_LD_FLAGS)
$(CC) $(TEST_CFLAGS) -o test/$(OS)/cfgutilstest cfgutilstest.o cfgutils.o cfg.o mtc.o log.o evtformat.o ctl.o transport.o backoff.o mtcformat.o strset.o com.o scopestdlib.o dbg.o circbuf.o linklist.o fn.o utils.o os.o test.o report.o search.o httpagg.o state.o httpstate.o metriccapture.o plattime.o $(TEST_AR) $(TEST_LD_FLAGS)
$(CC) $(TEST_CFLAGS) -o test/$(OS)/cfgtest cfgtest.o cfg.o scopestdlib.o dbg.o test.o $(TEST_AR) $(TEST_LD_FLAGS)
Expand Down
6 changes: 3 additions & 3 deletions os/linux/aarch64.mk
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ ARCH_LD_FLAGS=-lcapstone
ARCH_BINARY=elf64-littleaarch64
ARCH_OBJ=$(ARCH)

LD_FLAGS=$(MUSL_AR) $(UNWIND_AR) $(PCRE2_AR) $(LS_HPACK_AR) $(YAML_AR) $(JSON_AR) -ldl -lpthread -lrt -lresolv -Lcontrib/build/funchook -lfunchook -Lcontrib/build/funchook/capstone_src-prefix/src/capstone_src-build -lcapstone -z noexecstack
INCLUDES=-I./contrib/libyaml/include -I./contrib/cJSON -I./os/$(OS) -I./contrib/pcre2/src -I./contrib/build/pcre2 -I./contrib/funchook/capstone_src/include/ -I./contrib/jni -I./contrib/jni/linux/ -I./contrib/openssl/include -I./contrib/build/openssl/include -I./contrib/build/libunwind/include -I./contrib/libunwind/include/
LD_FLAGS=$(MUSL_AR) $(UNWIND_AR) $(COREDUMPER_AR) $(PCRE2_AR) $(LS_HPACK_AR) $(YAML_AR) $(JSON_AR) -ldl -lpthread -lrt -lresolv -Lcontrib/build/funchook -lfunchook -Lcontrib/build/funchook/capstone_src-prefix/src/capstone_src-build -lcapstone -z noexecstack
INCLUDES=-I./contrib/libyaml/include -I./contrib/cJSON -I./os/$(OS) -I./contrib/pcre2/src -I./contrib/build/pcre2 -I./contrib/funchook/capstone_src/include/ -I./contrib/jni -I./contrib/jni/linux/ -I./contrib/openssl/include -I./contrib/build/openssl/include -I./contrib/build/libunwind/include -I./contrib/libunwind/include/ -I./contrib/coredumper/src

$(LIBSCOPE): src/wrap.c src/state.c src/httpstate.c src/metriccapture.c src/report.c src/httpagg.c src/plattime.c src/fn.c os/$(OS)/os.c src/cfgutils.c src/cfg.c src/transport.c src/backoff.c src/log.c src/mtc.c src/circbuf.c src/linklist.c src/evtformat.c src/ctl.c src/mtcformat.c src/com.c src/scopestdlib.c src/dbg.c src/search.c src/wrap_go.c src/sysexec.c src/gocontext_arm.S src/scopeelf.c src/utils.c src/strset.c src/javabci.c src/javaagent.c src/ipc.c src/ipc_resp.c src/signalhandler.c
$(LIBSCOPE): src/wrap.c src/state.c src/httpstate.c src/metriccapture.c src/report.c src/httpagg.c src/plattime.c src/fn.c os/$(OS)/os.c src/cfgutils.c src/cfg.c src/transport.c src/backoff.c src/log.c src/mtc.c src/circbuf.c src/linklist.c src/evtformat.c src/ctl.c src/mtcformat.c src/com.c src/scopestdlib.c src/dbg.c src/search.c src/wrap_go.c src/sysexec.c src/gocontext_arm.S src/scopeelf.c src/utils.c src/strset.c src/javabci.c src/javaagent.c src/ipc.c src/ipc_resp.c src/signalhandler.c src/coredump.c
@$(MAKE) -C contrib funchook pcre2 openssl ls-hpack musl libyaml libunwind cJSON coredumper
@echo "$${CI:+::group::}Building $@"
$(CC) $(LIBRARY_CFLAGS) $(ARCH_CFLAGS) \
Expand Down
6 changes: 3 additions & 3 deletions os/linux/x86_64.mk
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ ARCH_LD_FLAGS=-lcapstone
ARCH_BINARY=elf64-x86-64
ARCH_OBJ=i386

LD_FLAGS=$(MUSL_AR) $(UNWIND_AR) $(PCRE2_AR) $(LS_HPACK_AR) $(YAML_AR) $(JSON_AR) -ldl -lpthread -lrt -Lcontrib/build/funchook -lfunchook -Lcontrib/build/funchook/capstone_src-prefix/src/capstone_src-build -lcapstone -z noexecstack
INCLUDES=-I./contrib/libyaml/include -I./contrib/cJSON -I./os/$(OS) -I./contrib/pcre2/src -I./contrib/build/pcre2 -I./contrib/funchook/capstone_src/include/ -I./contrib/jni -I./contrib/jni/linux/ -I./contrib/openssl/include -I./contrib/build/openssl/include -I./contrib/build/libunwind/include -I./contrib/libunwind/include/
LD_FLAGS=$(MUSL_AR) $(UNWIND_AR) $(COREDUMPER_AR) $(PCRE2_AR) $(LS_HPACK_AR) $(YAML_AR) $(JSON_AR) -ldl -lpthread -lrt -Lcontrib/build/funchook -lfunchook -Lcontrib/build/funchook/capstone_src-prefix/src/capstone_src-build -lcapstone -z noexecstack
INCLUDES=-I./contrib/libyaml/include -I./contrib/cJSON -I./os/$(OS) -I./contrib/pcre2/src -I./contrib/build/pcre2 -I./contrib/funchook/capstone_src/include/ -I./contrib/jni -I./contrib/jni/linux/ -I./contrib/openssl/include -I./contrib/build/openssl/include -I./contrib/build/libunwind/include -I./contrib/libunwind/include/ -I./contrib/coredumper/src

#ARCH_RM=&& rm ./test/selfinterpose/wrap_go.o
#ARCH_COPY=cp ./lib/$(OS)/$(ARCH)/libscope.so ./lib/$(OS)/libscope.so && \
# objcopy -I binary -O elf64-x86-64 -B i386 ./lib/$(OS)/libscope.so ./lib/$(OS)/libscope.o && \
# rm -f ./lib/$(OS)/libscope.so

$(LIBSCOPE): src/wrap.c src/state.c src/httpstate.c src/metriccapture.c src/report.c src/httpagg.c src/plattime.c src/fn.c os/$(OS)/os.c src/cfgutils.c src/cfg.c src/transport.c src/backoff.c src/log.c src/mtc.c src/circbuf.c src/linklist.c src/evtformat.c src/ctl.c src/mtcformat.c src/com.c src/scopestdlib.c src/dbg.c src/search.c src/sysexec.c src/gocontext.S src/scopeelf.c src/wrap_go.c src/utils.c src/strset.c src/javabci.c src/javaagent.c src/ipc.c src/ipc_resp.c src/signalhandler.c
$(LIBSCOPE): src/wrap.c src/state.c src/httpstate.c src/metriccapture.c src/report.c src/httpagg.c src/plattime.c src/fn.c os/$(OS)/os.c src/cfgutils.c src/cfg.c src/transport.c src/backoff.c src/log.c src/mtc.c src/circbuf.c src/linklist.c src/evtformat.c src/ctl.c src/mtcformat.c src/com.c src/scopestdlib.c src/dbg.c src/search.c src/sysexec.c src/gocontext.S src/scopeelf.c src/wrap_go.c src/utils.c src/strset.c src/javabci.c src/javaagent.c src/ipc.c src/ipc_resp.c src/signalhandler.c src/coredump.c
@$(MAKE) -C contrib funchook pcre2 openssl ls-hpack musl libyaml cJSON libunwind coredumper
@echo "$${CI:+::group::}Building $@"
$(CC) $(LIBRARY_CFLAGS) $(ARCH_CFLAGS) \
Expand Down
29 changes: 29 additions & 0 deletions src/coredump.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#define _GNU_SOURCE

#include "coredump.h"
#include "scopestdlib.h"
#include "utils.h"
#include "google/coredumper.h"


/*
* Generates core dump in location based on <pathPrefix><pid>
* Return status of operation
*/
bool
coreDumpGenerate(const char *pathPrefix, size_t pathPrefixSize, pid_t pid) {
char path[PATH_MAX] = {0};
if (pathPrefixSize > PATH_MAX) {
return FALSE;
}
scope_memcpy(path, pathPrefix, pathPrefixSize);
char pidBuf[32] = {0};
int msgLen = 0;
sigSafeUtoa(pid, pidBuf, 10, &msgLen);
if (pathPrefixSize + msgLen > PATH_MAX) {
return FALSE;
}
scope_memcpy(path + pathPrefixSize, pidBuf, msgLen);

return (WriteCoreDump(path) == 0);
}
8 changes: 8 additions & 0 deletions src/coredump.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#ifndef __COREDUMP_H__
#define __COREDUMP_H__

#include "scopetypes.h"

bool coreDumpGenerate(const char *, size_t, pid_t);

#endif // __COREDUMP_H__
6 changes: 6 additions & 0 deletions src/scopestdlib.c
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ extern gid_t scopelibc_getegid(void);
extern int scopelibc_seteuid(uid_t);
extern int scopelibc_setegid(gid_t);
extern gid_t scopelibc_getgid(void);
extern pid_t scopelibc_getpgrp(void);
extern void * scopelibc_dlopen(const char *, int);
extern int scopelibc_dlclose(void *);
extern void * scopelibc_dlsym(void *, const char *);
Expand Down Expand Up @@ -1054,6 +1055,11 @@ scope_getgid(void) {
return scopelibc_getgid();
}

pid_t
scope_getpgrp(void) {
return scopelibc_getpgrp();
}

void *
scope_dlopen(const char *filename, int flags) {
return scopelibc_dlopen(filename, flags);
Expand Down
1 change: 1 addition & 0 deletions src/scopestdlib.h
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,7 @@ gid_t scope_getegid(void);
int scope_seteuid(uid_t);
int scope_setegid(gid_t);
gid_t scope_getgid(void);
pid_t scope_getpgrp(void);
void* scope_dlopen(const char *, int);
void* scope_dlsym(void *, const char *);
int scope_dlclose(void *);
Expand Down
2 changes: 1 addition & 1 deletion src/signalhandler.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ scopeLogBacktrace(void) {
unw_context_t uc;
unw_word_t ip;

unw_getcontext(&uc);
unw_scope_getcontext(&uc);
unw_init_local(&cursor, &uc);
int frame_count = 0;
scopeLogErrorSigSafeCStr("--- scopeLogBacktrace\n");
Expand Down
1 change: 1 addition & 0 deletions test/unit/execute.sh
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ declare -i ERR=0
# Library tests
echo "Running Library Tests"
run_test test/${OS}/vdsotest
run_test test/${OS}/coredumptest
run_test test/${OS}/ipctest
run_test test/${OS}/strsettest
run_test test/${OS}/cfgutilstest
Expand Down
110 changes: 110 additions & 0 deletions test/unit/library/coredumptest.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
#define _GNU_SOURCE

#include "coredump.h"

#include "scopetypes.h"
#include "scopestdlib.h"
#include "scopeelf.h"

#include "test.h"

static char *
generateLongFileName(size_t max){
char *ptr = scope_calloc(1, sizeof(char) * (max + 1));
ptr[0] = '/';
for (int i = 1; i < max ;++i) {
ptr[i] = 'a';
}

return ptr;
}

// Basic check if file specified in path is a core file
static bool
checkIfElfCoreFile(const char* path) {
bool res = FALSE;
int fd = scope_open(path, O_RDONLY);
if (fd == -1) {
goto end;
}

Elf64_Ehdr *header = scope_malloc(sizeof(Elf64_Ehdr));
if (!header) {
goto close_file;
}

if (scope_read(fd, header, sizeof(Elf64_Ehdr)) == -1) {
goto free_header_buf;
}

// Verify ELF header
if (header->e_ident[EI_MAG0] != ELFMAG0
|| header->e_ident[EI_MAG1] != ELFMAG1
|| header->e_ident[EI_MAG2] != ELFMAG2
|| header->e_ident[EI_MAG3] != ELFMAG3) {
goto free_header_buf;
}

// Check for class
if (header->e_ident[EI_CLASS] != ELFCLASS64) {
goto free_header_buf;
}

// Check for type must point to core
if (header->e_type != ET_CORE) {
goto free_header_buf;
}

res = TRUE;

free_header_buf:
scope_free(header);

close_file:
scope_close(fd);

end:
return res;
}

static void
coreDumpFailureTooLongPath(void** state) {
char *path = generateLongFileName(PATH_MAX);
pid_t pid = scope_getpid();

bool coreRes = coreDumpGenerate(path, scope_strlen(path), pid);
assert_false(coreRes);
scope_free(path);
}

static void
coreDumpSuccess(void** state) {
char *prefix = "/tmp/scope_core.";
bool res;
int unlinkRes;
char pathBuf[1024] = {0};

pid_t pid = scope_getpid();
scope_snprintf(pathBuf, sizeof(pathBuf), "%s%d", prefix, pid);

res = coreDumpGenerate(prefix, scope_strlen(prefix), pid);
assert_true(res);

res = checkIfElfCoreFile(pathBuf);
assert_true(res);

unlinkRes = scope_unlink(pathBuf);
assert_int_equal(unlinkRes, 0);
}

int
main(int argc, char* argv[]) {
printf("running %s\n", argv[0]);

const struct CMUnitTest tests[] = {
cmocka_unit_test(coreDumpFailureTooLongPath),
cmocka_unit_test(coreDumpSuccess),
cmocka_unit_test(dbgHasNoUnexpectedFailures),
};
return cmocka_run_group_tests(tests, groupSetup, groupTeardown);
}

0 comments on commit 3db6605

Please sign in to comment.