Skip to content

Commit

Permalink
Use google breakpad in ydbd (#12894)
Browse files Browse the repository at this point in the history
  • Loading branch information
iddqdex authored Dec 24, 2024
1 parent 5034cc8 commit c594576
Show file tree
Hide file tree
Showing 8 changed files with 94 additions and 11 deletions.
1 change: 1 addition & 0 deletions ydb/apps/ydbd/ya.make
Original file line number Diff line number Diff line change
Expand Up @@ -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
)

Expand Down
12 changes: 1 addition & 11 deletions ydb/deploy/docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -24,30 +24,20 @@ 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
COPY --chmod=0755 --from=breakpad_init /usr/bin/minidump_stackwalk /usr/bin/minidump_stackwalk
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
Expand Down
34 changes: 34 additions & 0 deletions ydb/library/breakpad/minidumps.cpp
Original file line number Diff line number Diff line change
@@ -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;
14 changes: 14 additions & 0 deletions ydb/library/breakpad/ya.make
Original file line number Diff line number Diff line change
@@ -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()
1 change: 1 addition & 0 deletions ydb/library/ya.make
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ RECURSE(
arrow_parquet
backup
benchmarks
breakpad
chunks_limiter
folder_service
formats
Expand Down
18 changes: 18 additions & 0 deletions ydb/tests/functional/minidumps/test_break.py
Original file line number Diff line number Diff line change
@@ -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)
24 changes: 24 additions & 0 deletions ydb/tests/functional/minidumps/ya.make
Original file line number Diff line number Diff line change
@@ -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()
1 change: 1 addition & 0 deletions ydb/tests/functional/ya.make
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ RECURSE(
kv_workload
large_serializable
limits
minidumps
open_source
postgresql
query_cache
Expand Down

0 comments on commit c594576

Please sign in to comment.