536 backtrace_frame_filter_t filter) {
537 if (!symbols || count <= 0) {
538 SET_ERRNO(ERROR_INVALID_PARAM,
"Invalid parameters: symbols=%p, count=%d", symbols, count);
543 int start = skip_frames;
545 if (max_frames > 0 && (start + max_frames) < end) {
546 end = start + max_frames;
550 char colored_buffer[16384] = {0};
551 char plain_buffer[16384] = {0};
552 int colored_offset = 0;
553 int plain_offset = 0;
556 char log_header_buf[512] = {0};
557 time_t now = time(NULL);
558 struct tm *tm_info = localtime(&now);
560 strftime(timestamp,
sizeof(timestamp),
"%H:%M:%S", tm_info);
563 uint64_t tid_val = (uintptr_t)tid;
572 const char *colored_label_ptr =
colored_string(LOG_COLOR_WARN, label);
573 char colored_label_buf[256];
574 strncpy(colored_label_buf, colored_label_ptr,
sizeof(colored_label_buf) - 1);
575 colored_label_buf[
sizeof(colored_label_buf) - 1] =
'\0';
577 int len =
log_template_apply(format, log_header_buf,
sizeof(log_header_buf), LOG_WARN, timestamp, __FILE__,
578 __LINE__, __func__, tid_val, colored_label_buf,
true, time_ns);
581 colored_offset +=
safe_snprintf(colored_buffer + colored_offset,
sizeof(colored_buffer) - (
size_t)colored_offset,
582 "%s\n", log_header_buf);
585 safe_snprintf(log_header_buf,
sizeof(log_header_buf),
"[%s] [WARN] [tid:%llu] %s: %s", timestamp, tid_val,
587 const char *colored_header_ptr =
colored_string(LOG_COLOR_WARN, log_header_buf);
588 char colored_header_buf[512];
589 strncpy(colored_header_buf, colored_header_ptr,
sizeof(colored_header_buf) - 1);
590 colored_header_buf[
sizeof(colored_header_buf) - 1] =
'\0';
591 colored_offset +=
safe_snprintf(colored_buffer + colored_offset,
sizeof(colored_buffer) - (
size_t)colored_offset,
592 "%s\n", colored_header_buf);
596 safe_snprintf(log_header_buf,
sizeof(log_header_buf),
"[%s] [WARN] [tid:%llu] %s: %s", timestamp, tid_val, __func__,
598 const char *colored_header_ptr =
colored_string(LOG_COLOR_WARN, log_header_buf);
599 char colored_header_buf[512];
600 strncpy(colored_header_buf, colored_header_ptr,
sizeof(colored_header_buf) - 1);
601 colored_header_buf[
sizeof(colored_header_buf) - 1] =
'\0';
602 colored_offset +=
safe_snprintf(colored_buffer + colored_offset,
sizeof(colored_buffer) - (
size_t)colored_offset,
603 "%s\n", colored_header_buf);
608 safe_snprintf(plain_buffer + plain_offset,
sizeof(plain_buffer) - (
size_t)plain_offset,
"%s\n", label);
612 for (
int i = start; i < end && colored_offset < (int)
sizeof(colored_buffer) - 512; i++) {
613 const char *symbol = symbols[i] ? symbols[i] :
"???";
616 if (filter && filter(symbol)) {
621 char frame_num_str[16];
622 safe_snprintf(frame_num_str,
sizeof(frame_num_str),
"%d", frame_num);
625 const char *colored_num_ptr =
colored_string(LOG_COLOR_GREY, frame_num_str);
626 char colored_num_buf[256];
627 strncpy(colored_num_buf, colored_num_ptr,
sizeof(colored_num_buf) - 1);
628 colored_num_buf[
sizeof(colored_num_buf) - 1] =
'\0';
632 char colored_symbol[2048] = {0};
633 const char *s = symbol;
634 int colored_sym_offset = 0;
638 colored_sym_offset +=
639 safe_snprintf(colored_symbol + colored_sym_offset,
sizeof(colored_symbol) - colored_sym_offset,
"[");
642 const char *bracket_end = strchr(s,
']');
644 int bin_len = bracket_end - s;
646 strncpy(bin_name, s, bin_len);
647 bin_name[bin_len] =
'\0';
648 const char *colored_bin_ptr =
colored_string(LOG_COLOR_DEBUG, bin_name);
649 char colored_bin_buf[512];
650 strncpy(colored_bin_buf, colored_bin_ptr,
sizeof(colored_bin_buf) - 1);
651 colored_bin_buf[
sizeof(colored_bin_buf) - 1] =
'\0';
652 colored_sym_offset +=
safe_snprintf(colored_symbol + colored_sym_offset,
653 sizeof(colored_symbol) - colored_sym_offset,
"%s", colored_bin_buf);
654 colored_sym_offset +=
655 safe_snprintf(colored_symbol + colored_sym_offset,
sizeof(colored_symbol) - colored_sym_offset,
"] ");
661 while (*s && *s ==
' ')
665 const char *paren_start = strchr(s,
'(');
668 const char *colon_pos = strchr(s,
':');
669 if (colon_pos && paren_start && colon_pos < paren_start) {
672 int file_len = paren_start - s;
673 while (file_len > 0 && s[file_len - 1] ==
' ')
676 strncpy(file_part, s, file_len);
677 file_part[file_len] =
'\0';
680 const char *paren_end = strchr(paren_start,
')');
681 int desc_content_len = paren_end - paren_start - 1;
682 char desc_content[512];
683 strncpy(desc_content, paren_start + 1, desc_content_len);
684 desc_content[desc_content_len] =
'\0';
686 const char *colored_desc_ptr =
colored_string(LOG_COLOR_ERROR, desc_content);
687 char colored_desc_buf[512];
688 strncpy(colored_desc_buf, colored_desc_ptr,
sizeof(colored_desc_buf) - 1);
689 colored_desc_buf[
sizeof(colored_desc_buf) - 1] =
'\0';
690 colored_sym_offset +=
safe_snprintf(colored_symbol + colored_sym_offset,
691 sizeof(colored_symbol) - colored_sym_offset,
"(%s)", colored_desc_buf);
695 const char *file_start = file_part;
696 while (*file_start && *file_start ==
' ')
699 char *file_colon = strchr(file_start,
':');
701 int filename_len = file_colon - file_start;
703 strncpy(filename, file_start, filename_len);
704 filename[filename_len] =
'\0';
706 const char *colored_file_ptr =
colored_string(LOG_COLOR_DEBUG, filename);
707 char colored_file_buf[512];
708 strncpy(colored_file_buf, colored_file_ptr,
sizeof(colored_file_buf) - 1);
709 colored_file_buf[
sizeof(colored_file_buf) - 1] =
'\0';
711 const char *line_num = file_colon + 1;
712 const char *colored_line_ptr =
colored_string(LOG_COLOR_GREY, line_num);
713 char colored_line_buf[512];
714 strncpy(colored_line_buf, colored_line_ptr,
sizeof(colored_line_buf) - 1);
715 colored_line_buf[
sizeof(colored_line_buf) - 1] =
'\0';
717 colored_sym_offset +=
718 safe_snprintf(colored_symbol + colored_sym_offset,
sizeof(colored_symbol) - colored_sym_offset,
" (%s:%s)",
719 colored_file_buf, colored_line_buf);
721 }
else if (paren_start) {
723 int func_len = paren_start - s;
725 strncpy(func_name, s, func_len);
726 func_name[func_len] =
'\0';
728 const char *colored_func_ptr =
colored_string(LOG_COLOR_DEV, func_name);
729 char colored_func_buf[512];
730 strncpy(colored_func_buf, colored_func_ptr,
sizeof(colored_func_buf) - 1);
731 colored_func_buf[
sizeof(colored_func_buf) - 1] =
'\0';
732 colored_sym_offset +=
safe_snprintf(colored_symbol + colored_sym_offset,
733 sizeof(colored_symbol) - colored_sym_offset,
"%s()", colored_func_buf);
737 while (*s && *s !=
'(')
741 const char *file_paren_end = strchr(s,
')');
742 if (file_paren_end) {
743 colored_sym_offset +=
744 safe_snprintf(colored_symbol + colored_sym_offset,
sizeof(colored_symbol) - colored_sym_offset,
" (");
745 int file_len = file_paren_end - s - 1;
747 strncpy(file_part, s + 1, file_len);
748 file_part[file_len] =
'\0';
751 const char *file_start = file_part;
752 while (*file_start && *file_start ==
' ')
755 char *colon_pos = strchr(file_start,
':');
757 int filename_len = colon_pos - file_start;
759 strncpy(filename, file_start, filename_len);
760 filename[filename_len] =
'\0';
762 const char *colored_file_ptr =
colored_string(LOG_COLOR_DEBUG, filename);
763 char colored_file_buf[512];
764 strncpy(colored_file_buf, colored_file_ptr,
sizeof(colored_file_buf) - 1);
765 colored_file_buf[
sizeof(colored_file_buf) - 1] =
'\0';
767 const char *line_num = colon_pos + 1;
768 const char *colored_line_ptr =
colored_string(LOG_COLOR_GREY, line_num);
769 char colored_line_buf[512];
770 strncpy(colored_line_buf, colored_line_ptr,
sizeof(colored_line_buf) - 1);
771 colored_line_buf[
sizeof(colored_line_buf) - 1] =
'\0';
773 colored_sym_offset +=
774 safe_snprintf(colored_symbol + colored_sym_offset,
sizeof(colored_symbol) - colored_sym_offset,
"%s:%s",
775 colored_file_buf, colored_line_buf);
777 colored_sym_offset +=
778 safe_snprintf(colored_symbol + colored_sym_offset,
sizeof(colored_symbol) - colored_sym_offset,
")");
783 const char *colored_addr_ptr =
colored_string(LOG_COLOR_FATAL, s);
784 char colored_addr_buf[512];
785 strncpy(colored_addr_buf, colored_addr_ptr,
sizeof(colored_addr_buf) - 1);
786 colored_addr_buf[
sizeof(colored_addr_buf) - 1] =
'\0';
787 colored_sym_offset +=
safe_snprintf(colored_symbol + colored_sym_offset,
788 sizeof(colored_symbol) - colored_sym_offset,
"%s", colored_addr_buf);
792 colored_offset +=
safe_snprintf(colored_buffer + colored_offset,
sizeof(colored_buffer) - (
size_t)colored_offset,
793 " [%s] %s\n", colored_num_buf, colored_symbol);
796 plain_offset +=
safe_snprintf(plain_buffer + plain_offset,
sizeof(plain_buffer) - (
size_t)plain_offset,
797 " [%d] %s\n", frame_num, symbol);
804 fprintf(stderr,
"%s", colored_buffer);