Created
June 28, 2023 08:16
-
-
Save zhuizhuhaomeng/2a5c604eedb22b0cf07061aee0aadede to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
commit ffbb604ca72b709d8f77eebab7da97ec366c4f5b | |
Author: lijunlong <[email protected]> | |
Date: Wed Jun 28 16:10:40 2023 +0800 | |
bugfix: _stp_stack_user_sprint flush the buffer to the terminal when the log->buf is full. | |
diff --git a/runtime/linux/print.c b/runtime/linux/print.c | |
index 594b155be..8dbb3a800 100644 | |
--- a/runtime/linux/print.c | |
+++ b/runtime/linux/print.c | |
@@ -36,9 +36,13 @@ | |
*/ | |
struct _stp_log { | |
+ unsigned int dst_size; | |
+ unsigned int dst_len; | |
unsigned int len; /* Bytes used in the buffer */ | |
char *buf; /* NB we don't use arrays here to avoid allocating memory | |
on offline CPUs (but still possible ones) */ | |
+ char *dst; /* copy the buf into the dst when flushing buf for | |
+ _stp_snprintf */ | |
atomic_t reentrancy_lock; | |
}; | |
#include "print_flush.c" | |
diff --git a/runtime/print_flush.c b/runtime/print_flush.c | |
index 98963b3eb..f12431e0a 100644 | |
--- a/runtime/print_flush.c | |
+++ b/runtime/print_flush.c | |
@@ -30,6 +30,17 @@ static void __stp_print_flush(struct _stp_log *log) | |
log->len = 0; /* clear it for later reuse */ | |
dbug_trans(1, "len = %zu\n", len); | |
+ if (log->dst != NULL) { | |
+ if (log->dst_len < log->dst_size) { | |
+ size_t bytes; | |
+ | |
+ bytes = min_t(int, log->dst_size - log->dst_len, len); | |
+ memcpy(log->dst + log->dst_len, bufp, bytes); | |
+ log->dst_len += bytes; | |
+ } | |
+ return; | |
+ } | |
+ | |
/* try to reserve header + len */ | |
bytes_reserved = _stp_data_write_reserve(hlen+len, | |
&entry); | |
diff --git a/runtime/stack.c b/runtime/stack.c | |
index cdcee4bdd..011ec536d 100644 | |
--- a/runtime/stack.c | |
+++ b/runtime/stack.c | |
@@ -709,12 +709,25 @@ static void _stp_stack_kernel_sprint(char *str, int size, struct context* c, | |
} | |
log = per_cpu_ptr(_stp_log_pcpu, raw_smp_processor_id()); | |
+ log->dst = str; | |
+ log->dst_size = size - 1; | |
+ log->dst_len = 0; | |
+ | |
__stp_print_flush(log); | |
_stp_stack_kernel_print(c, sym_flags); | |
- bytes = min_t(int, size - 1, log->len); | |
- memcpy(str, log->buf, bytes); | |
+ | |
+ bytes = min_t(int, size - 1 - log->dst_len, log->len); | |
+ if (bytes > 0) | |
+ memcpy(str + log->dst_len, log->buf, bytes); | |
+ bytes += log->dst_len; | |
+ if ((sym_flags & _STP_SYM_POST_SPACE) && bytes > 0 && str[bytes] == ' ') | |
+ bytes--; | |
str[bytes] = '\0'; | |
log->len = 0; | |
+ log->dst = NULL; | |
+ log->dst_size = 0; | |
+ log->dst_len = 0; | |
+ | |
_stp_print_unlock_irqrestore(&flags); | |
} | |
@@ -737,11 +750,23 @@ static void _stp_stack_user_sprint(char *str, int size, struct context* c, | |
log = per_cpu_ptr(_stp_log_pcpu, raw_smp_processor_id()); | |
__stp_print_flush(log); | |
+ log->dst = str; | |
+ log->dst_size = size - 1; | |
+ log->dst_len = 0; | |
+ | |
_stp_stack_user_print(c, sym_flags); | |
- bytes = min_t(int, size - 1, log->len); | |
- memcpy(str, log->buf, bytes); | |
+ bytes = min_t(int, size - 1 - log->dst_len, log->len); | |
+ if (bytes > 0) | |
+ memcpy(str + log->dst_len, log->buf, bytes); | |
+ bytes += log->dst_len; | |
+ if ((sym_flags & _STP_SYM_POST_SPACE) && bytes > 0 && str[bytes] == ' ') | |
+ bytes--; | |
str[bytes] = '\0'; | |
log->len = 0; | |
+ log->dst = NULL; | |
+ log->dst_size = 0; | |
+ log->dst_len = 0; | |
+ | |
_stp_print_unlock_irqrestore(&flags); | |
} | |
diff --git a/testsuite/systemtap.base/ustack.exp b/testsuite/systemtap.base/ustack.exp | |
index 30671326a..9604d138f 100644 | |
--- a/testsuite/systemtap.base/ustack.exp | |
+++ b/testsuite/systemtap.base/ustack.exp | |
@@ -47,3 +47,25 @@ if {$res ne ""} { | |
send_log "stderr:\n$stderr" | |
} | |
} | |
+ | |
+# --- TEST 3 --- | |
+ | |
+set subtest3 "TEST 3: sprint_ubacktrace()" | |
+ | |
+set res [target_compile ${testpath}/${test}_3.c ./a.out executable \ | |
+ "additional_flags=-O additional_flags=-g additional_flags=-O0"] | |
+if {$res ne ""} { | |
+ verbose "target_compile failed: $res" 2 | |
+ fail "$test: $subtest2: unable to compile ${test}_3.c" | |
+} else { | |
+ set test_name "$test: $subtest3" | |
+ | |
+ set cmd "stap -DMAXBACKTRACE=256 --ldd -c ./a.out '$srcdir/$subdir/${test}_3.stp'" | |
+ set exit_code [run_cmd_2way $cmd out stderr] | |
+ set out_pat "bt: mark.*" | |
+ like "${test_name}: stdout" $out $out_pat "" | |
+ is "${test_name}: exit code" $exit_code 0 | |
+ if {$stderr ne ""} { | |
+ send_log "stderr:\n$stderr" | |
+ } | |
+} | |
diff --git a/testsuite/systemtap.base/ustack_3.c b/testsuite/systemtap.base/ustack_3.c | |
new file mode 100644 | |
index 000000000..d159562de | |
--- /dev/null | |
+++ b/testsuite/systemtap.base/ustack_3.c | |
@@ -0,0 +1,22 @@ | |
+void mark() | |
+{ | |
+} | |
+ | |
+int my_func_name_is_very_longlonglonglonglonglonglonglonglonglonglong(int depth) | |
+{ | |
+ int sum; | |
+ | |
+ if (depth <= 0) { | |
+ mark(); | |
+ return 0; | |
+ } | |
+ | |
+ sum = my_func_name_is_very_longlonglonglonglonglonglonglonglonglonglong(depth - 1); | |
+ sum += depth; | |
+ return sum; | |
+} | |
+ | |
+int main(void) { | |
+ my_func_name_is_very_longlonglonglonglonglonglonglonglonglonglong(200); | |
+ return 0; | |
+} | |
diff --git a/testsuite/systemtap.base/ustack_3.stp b/testsuite/systemtap.base/ustack_3.stp | |
new file mode 100644 | |
index 000000000..01f462ab3 | |
--- /dev/null | |
+++ b/testsuite/systemtap.base/ustack_3.stp | |
@@ -0,0 +1,5 @@ | |
+probe process.function("mark") { | |
+ s = sprint_ubacktrace(); | |
+ s = sprintf("bt: %s", s) | |
+ printf("%s", s); | |
+} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment