aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorОлег <150132506+iddqdex@users.noreply.github.com>2024-12-24 15:53:47 +0300
committerGitHub <noreply@github.com>2024-12-24 12:53:47 +0000
commitc594576c1c306b179df8cf75dddd145eca69fdc8 (patch)
treeec43d5643cf0db1fc114a899e8e388b0e23a6ed9
parent5034cc844a2c120e29c92e9f26bd5e73971ba265 (diff)
downloadydb-c594576c1c306b179df8cf75dddd145eca69fdc8.tar.gz
Use google breakpad in ydbd (#12894)
-rw-r--r--ydb/apps/ydbd/ya.make1
-rw-r--r--ydb/deploy/docker/Dockerfile12
-rw-r--r--ydb/library/breakpad/minidumps.cpp34
-rw-r--r--ydb/library/breakpad/ya.make14
-rw-r--r--ydb/library/ya.make1
-rw-r--r--ydb/tests/functional/minidumps/test_break.py18
-rw-r--r--ydb/tests/functional/minidumps/ya.make24
-rw-r--r--ydb/tests/functional/ya.make1
8 files changed, 94 insertions, 11 deletions
diff --git a/ydb/apps/ydbd/ya.make b/ydb/apps/ydbd/ya.make
index a3357b493d..7b5e03b4aa 100644
--- a/ydb/apps/ydbd/ya.make
+++ b/ydb/apps/ydbd/ya.make
@@ -67,6 +67,7 @@ PEERDIR(
yql/essentials/udfs/common/url_base
yql/essentials/udfs/common/yson2
yql/essentials/udfs/logs/dsv
+ ydb/library/breakpad
ydb/public/sdk/cpp/client/ydb_persqueue_public/codecs
)
diff --git a/ydb/deploy/docker/Dockerfile b/ydb/deploy/docker/Dockerfile
index 0a241f0576..f47740a3ce 100644
--- a/ydb/deploy/docker/Dockerfile
+++ b/ydb/deploy/docker/Dockerfile
@@ -24,21 +24,13 @@ COPY --chmod=0644 /liblibaio-dynamic.so /lib/liblibaio-dynamic.so
###
# Base image with google brekpad assets
###
-FROM ${BREAKPAD_INIT_IMAGE}:${BREAKPAD_INIT_IMAGE_TAG} AS breakpad_init
-
-
-FROM base AS breakpad-setuid
-COPY --from=breakpad_init /usr/lib/libbreakpad_init.so /usr/lib/libbreakpad_init.so
-# workaround for old docker versions
-# https://github.com/moby/buildkit/issues/3920
-RUN /usr/bin/chmod 4644 /usr/lib/libbreakpad_init.so
+FROM ${BREAKPAD_INIT_IMAGE}:${BREAKPAD_INIT_IMAGE_TAG} AS breakpad_init
FROM base AS base-breakpad
RUN \
apt-get -yqq update && \
apt-get -yqq install --no-install-recommends binutils gdb strace linux-tools-generic && \
apt-get clean && rm -rf /var/lib/apt/lists/*
-ENV LD_PRELOAD=libbreakpad_init.so
ENV BREAKPAD_MINIDUMPS_PATH=/opt/ydb/volumes/coredumps
ENV BREAKPAD_MINIDUMPS_SCRIPT=/opt/ydb/bin/minidump_script.py
# breakpad binaries
@@ -46,8 +38,6 @@ COPY --chmod=0755 --from=breakpad_init /usr/bin/minidump_stackwalk /usr/bin/mini
COPY --chmod=0755 --from=breakpad_init /usr/bin/minidump-2-core /usr/bin/minidump-2-core
# minidump callback script
COPY --chmod=0755 --chown=ydb /minidump_script.py /opt/ydb/bin/minidump_script.py
-# minidump init library
-COPY --link --from=breakpad-setuid /usr/lib/libbreakpad_init.so /usr/lib/libbreakpad_init.so
FROM base AS ydbd-setcap
COPY --chmod=0755 --chown=ydb /ydbd /opt/ydb/bin/ydbd
diff --git a/ydb/library/breakpad/minidumps.cpp b/ydb/library/breakpad/minidumps.cpp
new file mode 100644
index 0000000000..692ac67d4d
--- /dev/null
+++ b/ydb/library/breakpad/minidumps.cpp
@@ -0,0 +1,34 @@
+#include <util/generic/ptr.h>
+#include <contrib/libs/breakpad/src/client/linux/handler/exception_handler.h>
+#include <unistd.h>
+#include <sys/wait.h>
+
+
+class TMinidumper {
+public:
+ TMinidumper() {
+ if(const char* path = getenv("BREAKPAD_MINIDUMPS_PATH")) {
+ using namespace google_breakpad;
+ Handler = MakeHolder<ExceptionHandler>(MinidumpDescriptor(path), nullptr, DumpCallback, nullptr, true, -1, true);
+ }
+ }
+
+private:
+ static bool DumpCallback(const google_breakpad::MinidumpDescriptor& descriptor, void* context, bool succeeded) {
+ if (char* script = getenv("BREAKPAD_MINIDUMPS_SCRIPT")) {
+ if (auto pid = fork()) {
+ waitpid(pid, 0, 0);
+ } else {
+ char* dumpSucceded = succeeded ? (char *)"true" : (char *)"false";
+ char* descriptorPath = succeeded ? (char *)descriptor.path() : (char *)"\0";
+ char* cmd[] = {script, dumpSucceded, descriptorPath, NULL};
+ execve(cmd[0], &cmd[0], NULL);
+ }
+ }
+ return succeeded;
+ }
+
+ THolder<google_breakpad::ExceptionHandler> Handler;
+};
+
+TMinidumper Minidumper;
diff --git a/ydb/library/breakpad/ya.make b/ydb/library/breakpad/ya.make
new file mode 100644
index 0000000000..abb0a7c479
--- /dev/null
+++ b/ydb/library/breakpad/ya.make
@@ -0,0 +1,14 @@
+LIBRARY()
+
+IF (OS_LINUX)
+ PEERDIR(
+ contrib/libs/breakpad/src
+ contrib/libs/breakpad/src/client/linux
+ )
+
+ SRCS(
+ GLOBAL minidumps.cpp
+ )
+ENDIF()
+
+END()
diff --git a/ydb/library/ya.make b/ydb/library/ya.make
index ed6724d58e..20e9b74458 100644
--- a/ydb/library/ya.make
+++ b/ydb/library/ya.make
@@ -7,6 +7,7 @@ RECURSE(
arrow_parquet
backup
benchmarks
+ breakpad
chunks_limiter
folder_service
formats
diff --git a/ydb/tests/functional/minidumps/test_break.py b/ydb/tests/functional/minidumps/test_break.py
new file mode 100644
index 0000000000..ab3f137e23
--- /dev/null
+++ b/ydb/tests/functional/minidumps/test_break.py
@@ -0,0 +1,18 @@
+import yatest.common
+import os
+from ydb.tests.library.harness.kikimr_runner import KiKiMR
+
+
+def test_create_minidump():
+ dump_path = os.path.join(yatest.common.tempfile.gettempdir(), 'dumps')
+ os.makedirs(dump_path, exist_ok=True)
+ os.environ['BREAKPAD_MINIDUMPS_PATH'] = dump_path
+ cluster = KiKiMR()
+ cluster.start()
+ for node in cluster.nodes.values():
+ node.send_signal(6)
+ try:
+ cluster.stop()
+ except RuntimeError:
+ pass
+ assert len(os.listdir(dump_path)) == len(cluster.nodes)
diff --git a/ydb/tests/functional/minidumps/ya.make b/ydb/tests/functional/minidumps/ya.make
new file mode 100644
index 0000000000..7ab70d5293
--- /dev/null
+++ b/ydb/tests/functional/minidumps/ya.make
@@ -0,0 +1,24 @@
+IF (OS_LINUX)
+
+PY3TEST()
+
+TEST_SRCS(
+ test_break.py
+)
+
+SIZE(MEDIUM)
+
+ENV(YDB_DRIVER_BINARY="ydb/apps/ydbd/ydbd")
+
+PEERDIR(
+ ydb/tests/library
+)
+
+DEPENDS(
+ ydb/apps/ydbd
+)
+
+
+END()
+
+ENDIF()
diff --git a/ydb/tests/functional/ya.make b/ydb/tests/functional/ya.make
index 1590c3e71a..b1e60c8039 100644
--- a/ydb/tests/functional/ya.make
+++ b/ydb/tests/functional/ya.make
@@ -17,6 +17,7 @@ RECURSE(
kv_workload
large_serializable
limits
+ minidumps
open_source
postgresql
query_cache