Created
          June 28, 2023 08:16 
        
      - 
      
- 
        Save zhuizhuhaomeng/2a5c604eedb22b0cf07061aee0aadede to your computer and use it in GitHub Desktop. 
Revisions
- 
        zhuizhuhaomeng created this gist Jun 28, 2023 .There are no files selected for viewingThis 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,173 @@ 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); +}