代码拉取完成,页面将自动刷新
From 71fee80519b321b565cdec74d9e7fae25f9bc750 Mon Sep 17 00:00:00 2001
From: yinbin <yinbin8@huawei.com>
Date: Sat, 30 Nov 2024 16:05:02 +0800
Subject: [PATCH] DUMP: gazelle supports dump lstack
---
src/lstack/api/lstack_unistd.c | 36 +++-----
src/lstack/core/lstack_dump.c | 144 +++++++++++++++++++++++++++++++
src/lstack/include/lstack_dump.h | 19 ++++
3 files changed, 176 insertions(+), 23 deletions(-)
create mode 100644 src/lstack/core/lstack_dump.c
create mode 100644 src/lstack/include/lstack_dump.h
diff --git a/src/lstack/api/lstack_unistd.c b/src/lstack/api/lstack_unistd.c
index 1f78626..8fd6490 100644
--- a/src/lstack/api/lstack_unistd.c
+++ b/src/lstack/api/lstack_unistd.c
@@ -11,7 +11,6 @@
*/
#include <sys/types.h>
-#include <execinfo.h>
#include <sys/socket.h>
#include <lwip/lwipgz_sock.h>
@@ -22,28 +21,11 @@
#include "lstack_log.h"
#include "lstack_cfg.h"
#include "lstack_control_plane.h"
+#include "lstack_dump.h"
static int g_hijack_signal[] = { SIGTERM, SIGINT, SIGSEGV, SIGBUS, SIGFPE, SIGILL, SIGKILL};
#define HIJACK_SIGNAL_COUNT (sizeof(g_hijack_signal) / sizeof(g_hijack_signal[0]))
-#define BACKTRACE_SIZE 64
-static void dump_stack(void)
-{
- char **stack_trace = NULL;
- void *stack_array[BACKTRACE_SIZE];
- int stack_num = backtrace(stack_array, BACKTRACE_SIZE);
-
- stack_trace = (char**)backtrace_symbols(stack_array, stack_num);
- if (stack_trace == NULL) {
- perror("backtrace_symbols");
- return;
- }
-
- for (int i = 0; i < stack_num; i++) {
- LSTACK_LOG(ERR, LSTACK, "%s\n", stack_trace[i]);
- }
- free(stack_trace);
-}
static inline bool match_hijack_signal(int sig)
{
unsigned int i;
@@ -58,14 +40,22 @@ static inline bool match_hijack_signal(int sig)
static void lstack_sig_default_handler(int sig)
{
LSTACK_LOG(ERR, LSTACK, "lstack dumped, caught signal: %d\n", sig);
- if (get_global_cfg_params() && get_global_cfg_params()->is_primary) {
- delete_primary_path();
- }
- control_fd_close();
+
/* When operations such as pressing Ctrl+C or Kill, the call stack exit is not displayed. */
if (sig != SIGINT && sig != SIGTERM && sig != SIGKILL) {
+ /* dump stack info */
dump_stack();
+
+ /* dump internal information of lstack */
+ dump_lstack();
}
+
+ if (get_global_cfg_params() && get_global_cfg_params()->is_primary) {
+ delete_primary_path();
+ }
+
+ control_fd_close();
+
lwip_exit();
gazelle_exit();
(void)kill(getpid(), sig);
diff --git a/src/lstack/core/lstack_dump.c b/src/lstack/core/lstack_dump.c
new file mode 100644
index 0000000..d415ddc
--- /dev/null
+++ b/src/lstack/core/lstack_dump.c
@@ -0,0 +1,144 @@
+/*
+* Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. All rights reserved.
+* gazelle is licensed under the Mulan PSL v2.
+* You can use this software according to the terms and conditions of the Mulan PSL v2.
+* You may obtain a copy of Mulan PSL v2 at:
+* http://license.coscl.org.cn/MulanPSL2
+* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
+* PURPOSE.
+* See the Mulan PSL v2 for more details.
+*/
+
+#include <fcntl.h>
+#include <sys/time.h>
+#include <execinfo.h>
+
+#include "lstack_cfg.h"
+#include "lstack_log.h"
+
+#define DUMP_COMMAND_TIMEOUT_MS 2000
+#define DUMP_COMMAND_INTERVAL_MS 1
+#define DUMP_BUF_SZ 1024
+#define DUMP_BACKTRACE_SIZE 64
+
+static const char *dump_command[] = {
+ "gazellectl lstack show 1",
+ "gazellectl lstack show 1 -s",
+ "gazellectl lstack show 1 -x",
+ "gazellectl lstack show 1 -p UDP",
+ "gazellectl lstack show 1 -p TCP",
+ "gazellectl lstack show 1 -p ICMP",
+ "gazellectl lstack show 1 -p IP",
+ "gazellectl lstack show 1 -p ETHARP",
+ "gazellectl lstack show 1 -c"
+};
+
+static int dump_lstack_check(void)
+{
+ /* In ltran mode, dump commands maybe illegal */
+ if (use_ltran()) {
+ LSTACK_LOG(ERR, LSTACK, "ltran mode doesn't support lstack info dump.\n");
+ return -1;
+ }
+
+ LSTACK_LOG(INFO, LSTACK, "Dump lstack check passed. Dumping information:\n");
+ return 0;
+}
+
+#define US_PER_MS (MS_PER_S)
+static long timeval_diff_ms(struct timeval *end, struct timeval *begin)
+{
+ struct timeval result;
+ long result_ms;
+
+ result.tv_sec = end->tv_sec - begin->tv_sec;
+ result.tv_usec = end->tv_usec - begin->tv_usec;
+
+ result_ms = result.tv_sec * MS_PER_S + result.tv_usec / US_PER_MS;
+ return result_ms;
+}
+
+static int dump_command_excute(const char *command)
+{
+ FILE *fp;
+ int flags, fd;
+ char buffer[DUMP_BUF_SZ];
+ struct timeval start, now;
+ long elapsed;
+
+ if ((fp = popen(command, "r")) == NULL) {
+ LSTACK_LOG(ERR, LSTACK, "popen() failed, command \"%s\" didn't excute.\n", command);
+ return -1;
+ }
+
+ fd = fileno(fp);
+ flags = fcntl(fd, F_GETFL, 0);
+ fcntl(fd, F_SETFL, flags | O_NONBLOCK);
+
+ gettimeofday(&start, NULL);
+
+ /* Loop to print command output while checking for timeout. */
+ while (1) {
+ gettimeofday(&now, NULL);
+ elapsed = timeval_diff_ms(&now, &start);
+
+ /* check timeout */
+ if (elapsed > DUMP_COMMAND_TIMEOUT_MS) {
+ LSTACK_LOG(ERR, LSTACK, "Command timeout: %s\n", command);
+ pclose(fp);
+ return -1;
+ }
+
+ /* get and print command output */
+ if (fgets(buffer, sizeof(buffer), fp) != NULL) {
+ LSTACK_LOG(INFO, LSTACK, "\r %s", buffer);
+ } else if (feof(fp)) {
+ break;
+ } else {
+ usleep(DUMP_COMMAND_INTERVAL_MS * US_PER_MS); // 1ms
+ }
+ }
+
+ pclose(fp);
+ return 0;
+}
+
+void dump_lstack(void)
+{
+ int ret, command_count;
+
+ ret = dump_lstack_check();
+ if (ret < 0) {
+ LSTACK_LOG(ERR, LSTACK, "lstack dump check failed, dump process exited!\n");
+ return;
+ }
+
+ command_count = sizeof(dump_command) / sizeof(dump_command[0]);
+ for (int i = 0; i < command_count; ++i) {
+ LSTACK_LOG(INFO, LSTACK, "Dump command: \"%s\"\n", dump_command[i]);
+
+ ret = dump_command_excute(dump_command[i]);
+ if (ret < 0) {
+ LSTACK_LOG(ERR, LSTACK, "Dump command: \"%s\" excute failed.\n", dump_command[i]);
+ }
+ }
+}
+
+void dump_stack(void)
+{
+ char **stack_trace = NULL;
+ void *stack_array[DUMP_BACKTRACE_SIZE];
+ int stack_num = backtrace(stack_array, DUMP_BACKTRACE_SIZE);
+
+ stack_trace = (char**)backtrace_symbols(stack_array, stack_num);
+ if (stack_trace == NULL) {
+ LSTACK_LOG(ERR, LSTACK, "Error in backtrace_symbols, errno %d\n", errno);
+ return;
+ }
+
+ for (int i = 0; i < stack_num; i++) {
+ LSTACK_LOG(ERR, LSTACK, "%s\n", stack_trace[i]);
+ }
+ free(stack_trace);
+}
diff --git a/src/lstack/include/lstack_dump.h b/src/lstack/include/lstack_dump.h
new file mode 100644
index 0000000..83f2fd9
--- /dev/null
+++ b/src/lstack/include/lstack_dump.h
@@ -0,0 +1,19 @@
+/*
+* Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. All rights reserved.
+* gazelle is licensed under the Mulan PSL v2.
+* You can use this software according to the terms and conditions of the Mulan PSL v2.
+* You may obtain a copy of Mulan PSL v2 at:
+* http://license.coscl.org.cn/MulanPSL2
+* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
+* PURPOSE.
+* See the Mulan PSL v2 for more details.
+*/
+
+#ifndef _GAZELLE_DUMP_H_
+#define _GAZELLE_DUMP_H_
+
+void dump_stack(void);
+void dump_lstack(void);
+
+#endif /* _GAZELLE_DUMP_H_ */
--
2.33.0
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。