Skip to content

Commit fcb046b

Browse files
authored
add parent pid and registers collecting (#1616)
1 parent 84da284 commit fcb046b

10 files changed

Lines changed: 51 additions & 19 deletions

File tree

common/server/crash-dump.cpp

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,6 @@
1414
#include "common/ucontext/ucontext-portable.h"
1515
#include <ucontext.h>
1616

17-
struct crash_dump_buffer {
18-
char scratchpad[1024];
19-
size_t position;
20-
};
21-
using crash_dump_buffer_t = struct crash_dump_buffer;
22-
2317
static inline char crash_dump_half_byte_char(uint8_t hb) {
2418
if (hb <= 9) {
2519
return '0' + hb;
@@ -67,7 +61,7 @@ static inline void crash_dump_write_uint64(uint64_t value, crash_dump_buffer_t*
6761
// Keep in mind that:
6862
// * `ucontext_t_portable` -- using for more efficient user context manipulations (e.g. `swapcontext`, `getcontext`, `setcontext`, etc)
6963
// * `ucontext_t` -- using in signal handlers for machine state extracting in debug purposes.
70-
static inline void crash_dump_prepare_registers([[maybe_unused]] crash_dump_buffer_t* buffer, [[maybe_unused]] void* ucontext) {
64+
void crash_dump_prepare_registers([[maybe_unused]] crash_dump_buffer_t* buffer, [[maybe_unused]] const ucontext_t* uc) {
7165
#ifdef __x86_64__
7266
#ifdef __APPLE__
7367
const auto* uc = static_cast<ucontext_t*>(ucontext);
@@ -93,8 +87,6 @@ static inline void crash_dump_prepare_registers([[maybe_unused]] crash_dump_buff
9387
crash_dump_write_reg(LITERAL_WITH_LENGTH("R14=0x"), uc->uc_mcontext->__ss.__r14, buffer);
9488
crash_dump_write_reg(LITERAL_WITH_LENGTH("R15=0x"), uc->uc_mcontext->__ss.__r15, buffer);
9589
#else
96-
const auto* uc = static_cast<ucontext_t*>(ucontext);
97-
9890
crash_dump_write_reg(LITERAL_WITH_LENGTH("RIP=0x"), uc->uc_mcontext.gregs[REG_RIP], buffer);
9991
crash_dump_write_reg(LITERAL_WITH_LENGTH("RSP=0x"), uc->uc_mcontext.gregs[REG_RSP], buffer);
10092
crash_dump_write_reg(LITERAL_WITH_LENGTH("RBP=0x"), uc->uc_mcontext.gregs[REG_RBP], buffer);
@@ -131,7 +123,7 @@ void crash_dump_write(void* ucontext) {
131123

132124
static crash_dump_buffer_t buffer;
133125
buffer.position = 0;
134-
crash_dump_prepare_registers(&buffer, ucontext);
126+
crash_dump_prepare_registers(&buffer, static_cast<ucontext_t*>(ucontext));
135127

136128
assert(buffer.position < sizeof(buffer.scratchpad));
137129
buffer.scratchpad[buffer.position++] = '\n';

common/server/crash-dump.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,19 @@
33
// Distributed under the GPL v3 License, see LICENSE.notice.txt
44

55
#pragma once
6+
#include <cstddef>
7+
#include <cstdint>
8+
#include <string_view>
9+
#include <ucontext.h>
610

11+
struct crash_dump_buffer_t { // NOLINT
12+
char scratchpad[1024];
13+
size_t position{0};
14+
15+
std::string_view get_content() const noexcept {
16+
return std::string_view{scratchpad, position};
17+
}
18+
};
19+
20+
void crash_dump_prepare_registers(crash_dump_buffer_t* buffer, const ucontext_t* uc);
721
void crash_dump_write(void* ucontext);

server/json-logger.cpp

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,13 @@
66
#include <cinttypes>
77
#include <execinfo.h>
88
#include <fcntl.h>
9+
#include <ucontext.h>
910
#include <unistd.h>
11+
#include <memory>
1012

1113
#include "common/algorithms/find.h"
1214
#include "common/fast-backtrace.h"
15+
#include "common/server/crash-dump.h"
1316
#include "common/wrappers/likely.h"
1417
#include "common/ucontext/ucontext-portable.h"
1518
#include "runtime/kphp-backtrace.h"
@@ -259,7 +262,7 @@ void JsonLogger::write_log_with_demangled_backtrace(vk::string_view message,int
259262
}
260263

261264
void JsonLogger::write_log(vk::string_view message, int type, int64_t created_at,
262-
void *const *trace, int64_t trace_size, bool uncaught) noexcept {
265+
void *const *trace, int64_t trace_size, bool uncaught, void* ucontext) noexcept {
263266
if (json_log_fd_ <= 0) {
264267
return;
265268
}
@@ -269,7 +272,7 @@ void JsonLogger::write_log(vk::string_view message, int type, int64_t created_at
269272
}
270273
assert(json_out_it != buffers_.end());
271274

272-
write_general_info(json_out_it, type, created_at, uncaught);
275+
write_general_info(json_out_it, type, created_at, uncaught, ucontext);
273276

274277
json_out_it->append_key("trace").start<'['>();
275278
for (int64_t i = 0; i < trace_size; i++) {
@@ -324,7 +327,7 @@ void JsonLogger::reset_buffers() noexcept {
324327
}
325328
}
326329

327-
void JsonLogger::write_general_info(JsonBuffer *json_out_it, int type, int64_t created_at, bool uncaught) {
330+
void JsonLogger::write_general_info(JsonBuffer *json_out_it, int type, int64_t created_at, bool uncaught, void* ucontext) {
328331
json_out_it->append_key("version").append_integer(release_version_);
329332
json_out_it->append_key("hostname").append_string(hostname_);
330333
json_out_it->append_key("type").append_integer(type);
@@ -348,12 +351,25 @@ void JsonLogger::write_general_info(JsonBuffer *json_out_it, int type, int64_t c
348351
json_out_it->append_key("logname_id").append_integer(logname_id);
349352
}
350353
json_out_it->append_key("pid").append_integer(pid);
354+
json_out_it->append_key("ppid").append_integer(ppid);
351355
json_out_it->append_key("cluster").append_string(vk::singleton<ServerConfig>::get().get_cluster_name());
352356
json_out_it->append_raw(uncaught ? R"json("uncaught":true)json" : R"json("uncaught":false)json");
353357
json_out_it->finish<'}'>();
354358

355359
if (extra_info_available_) {
356-
json_out_it->append_key("extra_info").start<'{'>().append_raw(extra_info_).finish<'}'>();
360+
json_out_it->append_key("extra_info").start<'{'>().append_raw(extra_info_);
361+
if (ucontext != nullptr) {
362+
const auto* ucp = static_cast<ucontext_t*>(ucontext);
363+
364+
#if defined(__x86_64__) && !defined(__APPLE__)
365+
json_out_it->append_key("CR2 register").append_hex_as_string(ucp->uc_mcontext.gregs[REG_CR2]);
366+
#endif
367+
368+
crash_dump_buffer_t buffer{};
369+
crash_dump_prepare_registers(std::addressof(buffer), ucp);
370+
json_out_it->append_key("registers").append_string(buffer.get_content());
371+
}
372+
json_out_it->finish<'}'>();
357373
}
358374
}
359375

server/json-logger.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ class JsonLogger : vk::not_copyable {
4747
// ATTENTION: this functions are used in signal handlers, therefore they are expected to be safe for them
4848
// Details: https://man7.org/linux/man-pages/man7/signal-safety.7.html
4949
// todo: functions bellow use backtrace which isn't async-signal safety
50-
void write_log(vk::string_view message, int type, int64_t created_at, void *const *trace, int64_t trace_size, bool uncaught) noexcept;
50+
void write_log(vk::string_view message, int type, int64_t created_at, void *const *trace, int64_t trace_size, bool uncaught, void* ucontext = nullptr) noexcept;
5151
void write_log_with_backtrace(vk::string_view message, int type) noexcept;
5252
void write_log_with_script_backtrace(vk::string_view message, int type) noexcept;
5353

@@ -112,6 +112,6 @@ class JsonLogger : vk::not_copyable {
112112
};
113113
std::array<JsonBuffer, 8> buffers_;
114114

115-
void write_general_info(JsonBuffer * json_out_it, int type, int64_t created_at, bool uncaught);
115+
void write_general_info(JsonBuffer * json_out_it, int type, int64_t created_at, bool uncaught, void* ucontext = nullptr);
116116
};
117117

server/php-engine-vars.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ double oom_handling_memory_ratio = 0.00;
2222

2323
int worker_id = -1;
2424
int pid = -1;
25+
int ppid = -1;
2526
int master_pid = -1;
2627

2728
ProcessType process_type = ProcessType::master;

server/php-engine-vars.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ extern double oom_handling_memory_ratio;
3232

3333
extern int worker_id;
3434
extern int pid;
35+
extern int ppid;
3536
extern int master_pid;
3637

3738
extern ProcessType process_type;

server/php-engine.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2381,6 +2381,7 @@ void init_default() {
23812381
now = (int)time(nullptr);
23822382

23832383
pid = getpid();
2384+
ppid = getppid();
23842385
master_pid = getpid();
23852386
// RPC part
23862387
PID.port = -1; // TODO: get rid of this?

server/php-master.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -638,6 +638,7 @@ int run_worker(WorkerType worker_type) {
638638
//verbosity = 0;
639639
verbosity = initial_verbosity;
640640
pid = getpid();
641+
ppid = getppid();
641642

642643
master_sfd = -1;
643644
if (worker_type == WorkerType::job_worker) {

server/signal-handlers.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ void sigsegv_handler(int signum, siginfo_t *info, void *ucontext) {
195195
}
196196
} else {
197197
const char *msg = signum == SIGBUS ? "SIGBUS terminating program" : "SIGSEGV terminating program";
198-
vk::singleton<JsonLogger>::get().write_log(msg, static_cast<int>(ServerLog::Critical), cur_time, trace, trace_size, true);
198+
vk::singleton<JsonLogger>::get().write_log(msg, static_cast<int>(ServerLog::Critical), cur_time, trace, trace_size, true, ucontext);
199199
vk::singleton<JsonLogger>::get().fsync_log_file();
200200
write_str(2, "Error -2: Segmentation fault\n");
201201
print_http_data();
@@ -206,15 +206,15 @@ void sigsegv_handler(int signum, siginfo_t *info, void *ucontext) {
206206
}
207207
}
208208

209-
void sigabrt_handler(int, siginfo_t *info, void *) {
209+
void sigabrt_handler(int, siginfo_t *info, void *ucontext) {
210210
const int64_t cur_time = time(nullptr);
211211
void *trace[64];
212212
const int trace_size = backtrace(trace, 64);
213213
vk::string_view msg{dl_get_assert_message()};
214214
if (msg.empty()) {
215215
msg = "SIGABRT terminating program";
216216
}
217-
vk::singleton<JsonLogger>::get().write_log(msg, static_cast<int>(ServerLog::Critical), cur_time, trace, trace_size, true);
217+
vk::singleton<JsonLogger>::get().write_log(msg, static_cast<int>(ServerLog::Critical), cur_time, trace, trace_size, true, ucontext);
218218
vk::singleton<JsonLogger>::get().fsync_log_file();
219219

220220
print_prologue(cur_time);

tests/python/lib/kphp_server.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,13 @@ def _process_json_log(self, log_record):
8585
del log_record["tags"]["logname_id"]
8686
del log_record["tags"]["process_type"]
8787
del log_record["tags"]["pid"]
88+
del log_record["tags"]["ppid"]
8889
if not got_tags.get("cluster", ""):
8990
raise RuntimeError("Got an empty cluster in json log: {}".format(got_tags))
9091
del log_record["tags"]["cluster"]
92+
93+
if log_record.get("extra_info"):
94+
log_record["extra_info"].pop("CR2 register", None)
95+
log_record["extra_info"].pop("registers", None)
96+
9197
return log_record

0 commit comments

Comments
 (0)