From 31a375af532719dc0cc1f2afa694bb09132711b0 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 11 Dec 2018 10:57:47 +1030 Subject: [PATCH] lightningd: add runtime checking for all system-provided libs. And I tested this by rolling my own libz; make indeed detects the change and fixes it. Signed-off-by: Rusty Russell --- Makefile | 7 +++++-- lightningd/lightningd.c | 12 ++++++++++++ tools/headerversions.c | 38 +++++++++++++++++++++++++++++++++----- wallet/db.c | 4 ---- 4 files changed, 50 insertions(+), 11 deletions(-) diff --git a/Makefile b/Makefile index 149d0a95897b..d1aa77f1751f 100644 --- a/Makefile +++ b/Makefile @@ -342,8 +342,11 @@ tools/headerversions: FORCE tools/headerversions.o $(CCAN_OBJS) gen_header_versions.h: tools/headerversions @tools/headerversions $@ -# All binaries require the external libs, ccan and external library versions. -$(ALL_PROGRAMS) $(ALL_TEST_PROGRAMS): $(EXTERNAL_LIBS) $(CCAN_OBJS) gen_header_versions.h +# Rebuild the world if this changes. +ALL_GEN_HEADERS += gen_header_versions.h + +# All binaries require the external libs, ccan and system library versions. +$(ALL_PROGRAMS) $(ALL_TEST_PROGRAMS): $(EXTERNAL_LIBS) $(CCAN_OBJS) # Each test program depends on its own object. $(ALL_TEST_PROGRAMS): %: %.o diff --git a/lightningd/lightningd.c b/lightningd/lightningd.c index 6ec4c243784f..231dca0bb8b2 100644 --- a/lightningd/lightningd.c +++ b/lightningd/lightningd.c @@ -64,6 +64,7 @@ #include #include +#include #include #include #include @@ -581,6 +582,17 @@ int main(int argc, char *argv[]) /*~ What happens in strange locales should stay there. */ setup_locale(); + + /*~ This checks that the system-installed libraries (usually + * dynamically linked) actually are compatible with the ones we + * compiled with. + * + * The header itself is auto-generated every time the version of the + * installed libraries changes, as we had an sqlite3 version update + * which broke people, and "make" didn't think there was any work to + * do, so rebuilding didn't fix it. */ + check_linked_library_versions(); + /*~ Every daemon calls this in some form: the hooks are for dumping * backtraces when we crash (if supported on this platform). */ daemon_setup(argv[0], log_backtrace_print, log_backtrace_exit); diff --git a/tools/headerversions.c b/tools/headerversions.c index 4091dd5080c1..8adf4ef353d4 100644 --- a/tools/headerversions.c +++ b/tools/headerversions.c @@ -12,10 +12,42 @@ #include #include +static const char template[] = + "/* Generated file by tools/headerversions, do not edit! */\n" + "/* GMP version: %s */\n" + "/* SQLITE3 version: %u */\n" + "/* ZLIB version: %s */\n" + "#include \n" + "#include \n" + "#include \n" + "#include \n" + "\n" + "static inline void check_linked_library_versions(void)\n" + "{\n" + " char compiled_gmp_version[100];\n" + " if (SQLITE_VERSION_NUMBER != sqlite3_libversion_number())\n" + " errx(1, \"SQLITE version mismatch: compiled %%u, now %%u\",\n" + " SQLITE_VERSION_NUMBER, sqlite3_libversion_number());\n" + " /* zlib documents that first char alters ABI. Kudos! */\n" + " if (zlibVersion()[0] != ZLIB_VERSION[0])\n" + " errx(1, \"zlib version mismatch: compiled %%s, now %%s\",\n" + " ZLIB_VERSION, zlibVersion());\n" + " /* GMP doesn't say anything, and we have to assemble our own string. */\n" + " snprintf(compiled_gmp_version, sizeof(compiled_gmp_version),\n" + " \"%%u.%%u.%%u\",\n" + " __GNU_MP_VERSION,\n" + " __GNU_MP_VERSION_MINOR,\n" + " __GNU_MP_VERSION_PATCHLEVEL);\n" + " if (strcmp(compiled_gmp_version, gmp_version) != 0)\n" + " errx(1, \"gmp version mismatch: compiled %%s, now %%s\",\n" + " compiled_gmp_version, gmp_version);\n" + "}\n"; + int main(int argc, char *argv[]) { char *file, *new; + /* We don't bother with setup_locale(); we're a build tool */ err_set_progname(argv[0]); if (argc != 2) @@ -25,11 +57,7 @@ int main(int argc, char *argv[]) if (!file && errno != ENOENT) err(1, "Reading %s", argv[1]); - new = tal_fmt(NULL, - "/* Generated file by tools/headerversions, do not edit! */\n" - "/* GMP version: %s */\n" - "/* SQLITE3 version: %u */\n" - "/* ZLIB version: %s */\n", + new = tal_fmt(NULL, template, gmp_version, sqlite3_libversion_number(), zlibVersion()); diff --git a/wallet/db.c b/wallet/db.c index a7523161f6d4..9eb00d247cc1 100644 --- a/wallet/db.c +++ b/wallet/db.c @@ -546,10 +546,6 @@ static struct db *db_open(const tal_t *ctx, char *filename) struct db *db; sqlite3 *sql; - if (SQLITE_VERSION_NUMBER != sqlite3_libversion_number()) - db_fatal("SQLITE version mismatch: compiled %u, now %u", - SQLITE_VERSION_NUMBER, sqlite3_libversion_number()); - int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE; err = sqlite3_open_v2(filename, &sql, flags, NULL);