Some repositories couldn't be updated, please check application logs for details.
BadCredentialsException: 401 {"message": "Bad credentials", "documentation_url": "https://docs.github.com/rest", "status": "401"}

aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/ci.yml2
-rw-r--r--DEVELOPMENT.md14
-rw-r--r--Makefile26
-rwxr-xr-xscripts/flamegraph.sh1
-rw-r--r--src/CMakeLists.txt5
-rw-r--r--src/ci.c12
-rw-r--r--src/ci.h4
-rw-r--r--src/cmd_line.c2
-rw-r--r--src/file.c4
-rw-r--r--src/file.h8
-rw-r--r--src/net.h10
-rw-r--r--src/process.c13
-rw-r--r--src/process.h15
-rw-r--r--src/protocol.c10
-rw-r--r--src/protocol.h6
-rw-r--r--src/server.c4
-rw-r--r--src/storage.c4
-rw-r--r--src/storage.h2
-rw-r--r--src/storage_sqlite.c2
-rw-r--r--src/storage_sqlite.h2
-rw-r--r--src/worker.c8
21 files changed, 91 insertions, 63 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 205a033..91bdc70 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -107,7 +107,7 @@ jobs:
# sudo is used to resolve kernel symbols. Plus, it would be required
# if we didn't fix perf_event_paranoid. PATH needs to be preserved
# for FlameGraph.
- sudo --preserve-env=PATH make debug/flame_graphs
+ sudo --preserve-env=PATH DEBUGINFOD_URLS='https://debuginfod.ubuntu.com' make debug/flame_graphs
- name: Upload flame graphs
uses: actions/upload-artifact@v4
with:
diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md
index 59c5e9e..df3d0d8 100644
--- a/DEVELOPMENT.md
+++ b/DEVELOPMENT.md
@@ -1,3 +1,11 @@
+### Setting up
+
+Set up git hooks by running
+
+ ./scripts/setup-hooks.sh
+
+### Building
+
There's a Makefile with useful shortcuts to build the project in the "build/"
directory:
@@ -55,6 +63,12 @@ build/coverage/html:
The latest code coverage report for the `master` branch can be found at
https://egor-tensin.github.io/cimple/coverage/.
+### Static analysis
+
+Build w/ GCC's `-fanalyzer`:
+
+ make analyzer
+
### Flame graphs
Some performance analysis can be done by looking at flame graphs.
diff --git a/Makefile b/Makefile
index 342b3ef..2cebafc 100644
--- a/Makefile
+++ b/Makefile
@@ -1,16 +1,18 @@
include prelude.mk
-COMPILER ?= clang
-CONFIGURATION ?= debug
-DEFAULT_HOST ?= 127.0.0.1
-DEFAULT_PORT ?= 5556
-COVERAGE ?=
+COMPILER ?= clang
+CONFIGURATION ?= debug
+DEFAULT_HOST ?= 127.0.0.1
+DEFAULT_PORT ?= 5556
+COVERAGE ?=
+STATIC_ANALYZER ?=
$(eval $(call noexpand,COMPILER))
$(eval $(call noexpand,CONFIGURATION))
$(eval $(call noexpand,DEFAULT_HOST))
$(eval $(call noexpand,DEFAULT_PORT))
$(eval $(call noexpand,COVERAGE))
+$(eval $(call noexpand,STATIC_ANALYZER))
src_dir := $(abspath .)
build_dir := $(src_dir)/build
@@ -40,6 +42,7 @@ build:
-D 'DEFAULT_PORT=$(call escape,$(DEFAULT_PORT))' \
-D 'TEST_REPORT_DIR=$(call escape,$(build_dir)/test_report)' \
-D 'COVERAGE=$(call escape,$(COVERAGE))' \
+ -D 'STATIC_ANALYZER=$(call escape,$(STATIC_ANALYZER))' \
-D 'FLAME_GRAPHS_DIR=$(call escape,$(build_dir)/flame_graphs)' \
-S '$(call escape,$(src_dir))' \
-B '$(call escape,$(build_dir)/cmake)'
@@ -71,6 +74,16 @@ ifndef CI
xdg-open '$(call escape,$(build_dir))/html/index.html' &> /dev/null
endif
+# This a separate target, because CMake is kinda dumb; if you run `make debug`
+# and then `make debug COMPILER=gcc STATIC_ANALYZER=1`, it'll run a rebuild,
+# but won't include the -fanalyzer option for some reason.
+.PHONY: analyzer
+analyzer analyzer/%: CONFIGURATION := debug
+analyzer analyzer/%: COMPILER := gcc
+analyzer analyzer/%: STATIC_ANALYZER := 1
+analyzer analyzer/%: build_dir := $(build_dir)/analyzer
+analyzer: build
+
%/install: % DO
cmake --install '$(call escape,$(build_dir))/cmake'
@@ -107,9 +120,6 @@ endif
ctest --test-dir '$(call escape,$(build_dir))/cmake' \
--verbose --tests-regex python_tests_valgrind
-# When building a Docker image for a different platform, exclude stress tests:
-# they simply take way too long.
-
%/flame_graphs: DO
@echo -----------------------------------------------------------------
@echo Generating flame graphs
diff --git a/scripts/flamegraph.sh b/scripts/flamegraph.sh
index 3a6c9e2..7baf084 100755
--- a/scripts/flamegraph.sh
+++ b/scripts/flamegraph.sh
@@ -101,6 +101,7 @@ main() {
--freq=99 \
--call-graph dwarf,65528 \
--pid="$pids" \
+ ${DEBUGINFOD_URLS:+--debuginfod} \
--no-inherit &
record_pid="$!"
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index ca19416..7bd8e78 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -9,6 +9,11 @@ if(COVERAGE)
add_link_options(--coverage)
endif()
+option(STATIC_ANALYZER "Enable static analysis")
+if(STATIC_ANALYZER)
+ add_compile_options(-fanalyzer)
+endif()
+
# Valgrind on Ubuntu Focal doesn't like DWARF version 5 debug info generated
# by Clang 14.
if("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang")
diff --git a/src/ci.c b/src/ci.c
index 0e40548..d906fc4 100644
--- a/src/ci.c
+++ b/src/ci.c
@@ -31,13 +31,13 @@ static const char *ci_env[] = {
};
/* clang-format on */
-static int ci_run_script(const char *script, struct proc_output *result)
+static int ci_run_script(const char *script, struct process_output *result)
{
const char *args[] = {script, NULL};
- return proc_capture(args, ci_env, result);
+ return process_execute_and_capture(args, ci_env, result);
}
-int ci_run(struct proc_output *result)
+int ci_run(struct process_output *result)
{
for (const char **script = ci_scripts; *script; ++script) {
if (!file_exists(*script))
@@ -76,7 +76,7 @@ cleanup_repo:
return ret;
}
-int ci_run_git_repo(const char *url, const char *rev, struct proc_output *output)
+int ci_run_git_repo(const char *url, const char *rev, struct process_output *output)
{
char *oldpwd = NULL;
git_repository *repo = NULL;
@@ -86,7 +86,7 @@ int ci_run_git_repo(const char *url, const char *rev, struct proc_output *output
if (ret < 0)
goto exit;
- ret = my_chdir(git_repository_workdir(repo), &oldpwd);
+ ret = chdir_wrapper(git_repository_workdir(repo), &oldpwd);
if (ret < 0)
goto free_repo;
@@ -95,7 +95,7 @@ int ci_run_git_repo(const char *url, const char *rev, struct proc_output *output
goto oldpwd;
oldpwd:
- my_chdir(oldpwd, NULL);
+ chdir_wrapper(oldpwd, NULL);
free(oldpwd);
free_repo:
diff --git a/src/ci.h b/src/ci.h
index 397f4a7..542243c 100644
--- a/src/ci.h
+++ b/src/ci.h
@@ -10,7 +10,7 @@
#include "process.h"
-int ci_run(struct proc_output *);
+int ci_run(struct process_output *);
/*
* This is a high-level function. It's basically equivalent to the following
@@ -25,6 +25,6 @@ int ci_run(struct proc_output *);
* rm -rf "$dir"
*
*/
-int ci_run_git_repo(const char *url, const char *rev, struct proc_output *);
+int ci_run_git_repo(const char *url, const char *rev, struct process_output *);
#endif
diff --git a/src/cmd_line.c b/src/cmd_line.c
index 35b27a7..bf3aa24 100644
--- a/src/cmd_line.c
+++ b/src/cmd_line.c
@@ -16,7 +16,7 @@
static char *get_current_binary_path(void)
{
- return my_readlink("/proc/self/exe");
+ return readlink_wrapper("/proc/self/exe");
}
static char *get_current_binary_name(void)
diff --git a/src/file.c b/src/file.c
index a0a8f8a..90ee905 100644
--- a/src/file.c
+++ b/src/file.c
@@ -36,7 +36,7 @@ int rm_rf(const char *dir)
return nftw(dir, unlink_cb, 64, FTW_DEPTH | FTW_PHYS);
}
-int my_chdir(const char *dir, char **old)
+int chdir_wrapper(const char *dir, char **old)
{
int ret = 0;
@@ -63,7 +63,7 @@ free_old:
return ret;
}
-char *my_readlink(const char *path)
+char *readlink_wrapper(const char *path)
{
size_t current_size = 256;
char *buf = NULL;
diff --git a/src/file.h b/src/file.h
index 54bb5fb..9c228a4 100644
--- a/src/file.h
+++ b/src/file.h
@@ -12,8 +12,12 @@
int rm_rf(const char *dir);
-int my_chdir(const char *dir, char **old);
-char *my_readlink(const char *path);
+/* This chdir(2) wrapper optionally saves the previous working directory in the
+ * `old` pointer, allowing the user to switch back to it if necessary. */
+int chdir_wrapper(const char *dir, char **old);
+
+/* This readlink(2) wrapper allocates enough memory dynamically. */
+char *readlink_wrapper(const char *path);
int file_dup(int fd);
void file_close(int fd);
diff --git a/src/net.h b/src/net.h
index 8ed0958..2769b13 100644
--- a/src/net.h
+++ b/src/net.h
@@ -11,7 +11,6 @@
#include "buf.h"
#include <stddef.h>
-#include <stdint.h>
int net_bind(const char *port);
int net_accept(int fd);
@@ -21,15 +20,6 @@ void net_close(int fd);
int net_send(int fd, const void *, size_t);
int net_recv(int fd, void *, size_t);
-struct buf;
-
-int buf_create(struct buf **, const void *, uint32_t);
-int buf_create_from_string(struct buf **, const char *);
-void buf_destroy(struct buf *);
-
-uint32_t buf_get_size(const struct buf *);
-const void *buf_get_data(const struct buf *);
-
int net_send_buf(int fd, const struct buf *);
int net_recv_buf(int fd, struct buf **);
diff --git a/src/process.c b/src/process.c
index 580daaf..1c452ac 100644
--- a/src/process.c
+++ b/src/process.c
@@ -58,7 +58,7 @@ static int wait_for_child(pid_t pid, int *ec)
return 0;
}
-int proc_spawn(const char *args[], const char *envp[], int *ec)
+int process_execute(const char *args[], const char *envp[], int *ec)
{
pid_t child_pid = fork();
if (child_pid < 0) {
@@ -93,7 +93,8 @@ static int redirect_and_exec_child(int pipe_fds[2], const char *args[], const ch
return exec_child(args, envp);
}
-int proc_capture(const char *args[], const char *envp[], struct proc_output *result)
+int process_execute_and_capture(const char *args[], const char *envp[],
+ struct process_output *result)
{
static const int flags = O_CLOEXEC;
int pipe_fds[2];
@@ -137,9 +138,9 @@ close_pipe:
return ret;
}
-int proc_output_create(struct proc_output **_output)
+int process_output_create(struct process_output **_output)
{
- struct proc_output *output = calloc(1, sizeof(struct proc_output));
+ struct process_output *output = calloc(1, sizeof(struct process_output));
if (!output) {
log_errno("calloc");
return -1;
@@ -153,13 +154,13 @@ int proc_output_create(struct proc_output **_output)
return 0;
}
-void proc_output_destroy(struct proc_output *output)
+void process_output_destroy(struct process_output *output)
{
free(output->data);
free(output);
}
-void proc_output_dump(const struct proc_output *output)
+void process_output_dump(const struct process_output *output)
{
log("Process exit code: %d\n", output->ec);
log("Process output: %zu bytes\n", output->data_size);
diff --git a/src/process.h b/src/process.h
index 810010d..965cb5e 100644
--- a/src/process.h
+++ b/src/process.h
@@ -10,24 +10,25 @@
#include <stddef.h>
-struct proc_output {
+struct process_output {
int ec;
unsigned char *data;
size_t data_size;
};
/* The exit code is only valid if the functions returns a non-negative number. */
-int proc_spawn(const char *args[], const char *envp[], int *ec);
+int process_execute(const char *args[], const char *envp[], int *ec);
-/* Similarly, the contents of the proc_output structure is only valid if the function returns a
+/* Similarly, the contents of the process_output structure is only valid if the function returns a
* non-negative number.
*
* In that case, you'll need to free the output. */
-int proc_capture(const char *args[], const char *envp[], struct proc_output *result);
+int process_execute_and_capture(const char *args[], const char *envp[],
+ struct process_output *result);
-int proc_output_create(struct proc_output **);
-void proc_output_destroy(struct proc_output *);
+int process_output_create(struct process_output **);
+void process_output_destroy(struct process_output *);
-void proc_output_dump(const struct proc_output *);
+void process_output_dump(const struct process_output *);
#endif
diff --git a/src/protocol.c b/src/protocol.c
index d950004..0fa06f1 100644
--- a/src/protocol.c
+++ b/src/protocol.c
@@ -120,7 +120,7 @@ static const char *const finished_key_ec = "exit_code";
static const char *const finished_key_data = "output";
int request_create_finished_run(struct jsonrpc_request **request, int run_id,
- const struct proc_output *output)
+ const struct process_output *output)
{
int ret = 0;
@@ -153,12 +153,12 @@ free_request:
}
int request_parse_finished_run(const struct jsonrpc_request *request, int *_run_id,
- struct proc_output **_output)
+ struct process_output **_output)
{
int ret = 0;
- struct proc_output *output = NULL;
- ret = proc_output_create(&output);
+ struct process_output *output = NULL;
+ ret = process_output_create(&output);
if (ret < 0)
return ret;
@@ -187,7 +187,7 @@ int request_parse_finished_run(const struct jsonrpc_request *request, int *_run_
return ret;
free_output:
- proc_output_destroy(output);
+ process_output_destroy(output);
return ret;
}
diff --git a/src/protocol.h b/src/protocol.h
index 2277998..c496449 100644
--- a/src/protocol.h
+++ b/src/protocol.h
@@ -21,8 +21,10 @@ int request_parse_new_worker(const struct jsonrpc_request *);
int request_create_start_run(struct jsonrpc_request **, const struct run *);
int request_parse_start_run(const struct jsonrpc_request *, struct run **);
-int request_create_finished_run(struct jsonrpc_request **, int run_id, const struct proc_output *);
-int request_parse_finished_run(const struct jsonrpc_request *, int *run_id, struct proc_output **);
+int request_create_finished_run(struct jsonrpc_request **, int run_id,
+ const struct process_output *);
+int request_parse_finished_run(const struct jsonrpc_request *, int *run_id,
+ struct process_output **);
int request_create_get_runs(struct jsonrpc_request **);
int request_parse_get_runs(const struct jsonrpc_request *);
diff --git a/src/server.c b/src/server.c
index 89ffcb1..b917f7c 100644
--- a/src/server.c
+++ b/src/server.c
@@ -297,7 +297,7 @@ static int server_handle_cmd_finished_run(const struct jsonrpc_request *request,
int ret = 0;
int run_id = 0;
- struct proc_output *output;
+ struct process_output *output;
ret = request_parse_finished_run(request, &run_id, &output);
if (ret < 0)
@@ -312,7 +312,7 @@ static int server_handle_cmd_finished_run(const struct jsonrpc_request *request,
log("Marked run %d as finished\n", run_id);
free_output:
- proc_output_destroy(output);
+ process_output_destroy(output);
return ret;
}
diff --git a/src/storage.c b/src/storage.c
index 43e871f..54a62c2 100644
--- a/src/storage.c
+++ b/src/storage.c
@@ -18,7 +18,7 @@ typedef int (*storage_create_t)(struct storage *, const struct storage_settings
typedef void (*storage_destroy_t)(struct storage *);
typedef int (*storage_run_create_t)(struct storage *, const char *repo_url, const char *rev);
-typedef int (*storage_run_finished_t)(struct storage *, int repo_id, const struct proc_output *);
+typedef int (*storage_run_finished_t)(struct storage *, int repo_id, const struct process_output *);
typedef int (*storage_get_runs_t)(struct storage *, struct run_queue *);
typedef storage_get_runs_t storage_get_run_queue_t;
@@ -105,7 +105,7 @@ int storage_run_create(struct storage *storage, const char *repo_url, const char
return api->run_create(storage, repo_url, rev);
}
-int storage_run_finished(struct storage *storage, int run_id, const struct proc_output *output)
+int storage_run_finished(struct storage *storage, int run_id, const struct process_output *output)
{
const struct storage_api *api = get_api(storage->type);
if (!api)
diff --git a/src/storage.h b/src/storage.h
index c50444d..01ec25a 100644
--- a/src/storage.h
+++ b/src/storage.h
@@ -36,7 +36,7 @@ int storage_create(struct storage *, const struct storage_settings *);
void storage_destroy(struct storage *);
int storage_run_create(struct storage *, const char *repo_url, const char *rev);
-int storage_run_finished(struct storage *, int run_id, const struct proc_output *);
+int storage_run_finished(struct storage *, int run_id, const struct process_output *);
int storage_get_runs(struct storage *, struct run_queue *);
int storage_get_run_queue(struct storage *, struct run_queue *);
diff --git a/src/storage_sqlite.c b/src/storage_sqlite.c
index 6c8a26f..efefaf0 100644
--- a/src/storage_sqlite.c
+++ b/src/storage_sqlite.c
@@ -410,7 +410,7 @@ int storage_sqlite_run_create(struct storage *storage, const char *repo_url, con
}
int storage_sqlite_run_finished(struct storage *storage, int run_id,
- const struct proc_output *output)
+ const struct process_output *output)
{
struct prepared_stmt *stmt = &storage->sqlite->stmt_run_finished;
int ret = 0;
diff --git a/src/storage_sqlite.h b/src/storage_sqlite.h
index 2d82496..2a4df2b 100644
--- a/src/storage_sqlite.h
+++ b/src/storage_sqlite.h
@@ -24,7 +24,7 @@ int storage_sqlite_create(struct storage *, const struct storage_settings *);
void storage_sqlite_destroy(struct storage *);
int storage_sqlite_run_create(struct storage *, const char *repo_url, const char *rev);
-int storage_sqlite_run_finished(struct storage *, int id, const struct proc_output *);
+int storage_sqlite_run_finished(struct storage *, int id, const struct process_output *);
int storage_sqlite_get_runs(struct storage *, struct run_queue *runs);
int storage_sqlite_get_run_queue(struct storage *, struct run_queue *runs);
diff --git a/src/worker.c b/src/worker.c
index 5c0ab96..8ee0703 100644
--- a/src/worker.c
+++ b/src/worker.c
@@ -179,8 +179,8 @@ static int worker_do_run(struct worker *worker)
{
int ret = 0;
- struct proc_output *result = NULL;
- ret = proc_output_create(&result);
+ struct process_output *result = NULL;
+ ret = process_output_create(&result);
if (ret < 0)
return ret;
@@ -190,7 +190,7 @@ static int worker_do_run(struct worker *worker)
goto free_output;
}
- proc_output_dump(result);
+ process_output_dump(result);
struct jsonrpc_request *finished_request = NULL;
@@ -214,7 +214,7 @@ free_request:
jsonrpc_request_destroy(finished_request);
free_output:
- proc_output_destroy(result);
+ process_output_destroy(result);
run_destroy(worker->run);