-
Notifications
You must be signed in to change notification settings - Fork 618
os/kernel/crashlog_writer: Add crash log flash save #6899
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
os/kernel/log_dump/log_dump.c
Outdated
| static unsigned char compressed_buf[ASSERT_LOG_BUF_SIZE]; | ||
| static unsigned int compressed_buf_size; | ||
| static char assert_log[ASSERT_LOG_BUF_SIZE]; | ||
| static int assert_situation=0; | ||
| static int assert_log_index=0; | ||
| static int log_len=0; | ||
|
|
||
| /* Structures used to decompress and print compressed log data*/ | ||
| static char tm[ASSERT_LOG_BUF_SIZE]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It appears that this feature is not utilizing the same buffer as the existing log_dump.
In that case, please proceed with adding a completely new file.
| * This is used to store logs that are output via lldbg() during a user crash situation into a buffer. | ||
| * | ||
| ****************************************************************************/ | ||
| void assert_log_to_buffer(FAR const char *fmt, va_list ap); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
which code is calling this?
os/arch/arm/src/armv7-a/arm_assert.c
Outdated
| #ifdef CONFIG_BINMGR_RECOVERY | ||
| if (IS_FAULT_IN_USER_SPACE(asserted_location)) { | ||
| /* start assert log saving */ | ||
| set_assert_situation(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
our crash code is started on fault isr like arm_dataabort.c
the fault isr logs also matter.
And do we need to make start log saving point?
| set_notassert_situation(); | ||
| assert_log_to_file(); | ||
| assert_log_compress(); | ||
| compressed_assert_log_to_file(); | ||
| compressed_assert_log_read(); | ||
| decompress_and_print(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the functions are calling here only,
we don't need to call theae seperatly.
How about call onec api here?
log_dump_crash_save_to_file()
os/kernel/log_dump/log_dump.c
Outdated
| void assert_log_compress(){ | ||
|
|
||
| lldbg("\n\n================compress start==============\n\n"); | ||
| compressed_buf_size=ASSERT_LOG_BUF_SIZE; | ||
| compress_block(compressed_buf,&compressed_buf_size,assert_log,ASSERT_LOG_BUF_SIZE); | ||
| lldbg("compressed buf size: %d\n",compressed_buf_size); | ||
| lldbg("\n====================compress end =====================\n"); | ||
|
|
||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code is exculed during crash recovery.
So, we need check time for compress.
If It is long, not compress is better.
for it, How about make configuration compress or not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I conducted an experiment where, after printing the entire log, I measured the time it takes to save the log to a file using clock(). The measurement was repeated multiple times.
- When the log size was 5370 bytes:
-With compression-
run run1 run2 run3 run4 run5 mean
time(s) 0.09 0.129 0.042 0.091 0.134 0.0972
compressed size: 1638 bytes
-Without compression-
run run1 run2 run3 run4 run5 mean
time(s) 0.037 0.033 0.082 0.357 0.034 0.095
- When the log size was 27971 bytes (It was randomly generated using rand()):
-With compression-
run run1 run2 run3 run4 run5 mean
time(s) 0.046 0.374 0.046 0.136 0.093 0.139
comp size(bytes) 3596 4483 3523 3593 3591
-Without compression-
run run1 run2 run3 run4 run5 mean
time(s) 0.883 0.355 0.58 0.269 0.079 0.256
When the log size is small, the time taken is similar whether compression is used or not. However, as the log size increases, using compression becomes faster overall. It seems that the time spent on writing dominates more than the time spent on compression. Therefore, it may not be necessary to create a separate configuration for this.
| compressed_assert_log_read(); | ||
| decompress_and_print(); | ||
| /* Create loader to reload binary */ | ||
| ret = binary_manager_execute_loader(LOADCMD_RELOAD, bin_idx); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we need to make option to system reboot here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please check coding rule
os/kernel/log_dump/log_dump.c
Outdated
| return -1; | ||
| } | ||
| lldbg("file open success\n"); | ||
| int log_size=write(fd,assert_log,strlen(assert_log)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
below is better code.
int len = strlen(assert_log);
int ret = write(fd, assert_log, len);
close(fd);
if (ret != len) {
lldbg("file write failed ret : %d len : %d errno : %d\n", ret, len, errno);
return -1;
}
os/kernel/log_dump/log_dump.c
Outdated
| int ret=write(fd,compressed_buf,compressed_buf_size); | ||
| if(ret<0){ | ||
| lldbg("file write failed\n"); | ||
| return -1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
file should be closed here.
os/kernel/log_dump/log_dump.c
Outdated
| } | ||
| int compressed_assert_log_to_file(){ | ||
| lldbg("\n\n================compress file write start==============\n\n"); | ||
| int fd=open("/mnt/ssert_logsave_zip",O_WRONLY|O_CREAT|O_TRUNC); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use macro for /mnt/ssert_logsave_zip would be better.
os/kernel/log_dump/log_dump.c
Outdated
| } | ||
| int set_assert_situation(){ | ||
| lldbg("\n\n\n===============================FROM THIS, lldbg LOG WILL BE SAVED!!================================\n\n\n\n"); | ||
| assert_situation=1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can use assert_situation = true;
os/include/syslog.h
Outdated
| */ | ||
| int lowvsyslog(int priority, FAR const char *format, va_list ap); | ||
|
|
||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unnecessary file changes
dba5e00 to
8cfcc29
Compare
Developed a new feature to store logs during assert situations. It only operates when a crash occurs in the user space. The following modifications are required: 1. Avoid using double vsnprintf. -> resolved 2. Check available space in the file system before wrting. 3. Check available heap memory before compression. 4. Store compressed data in the heap instead of the data section. -> resolved 5. Add a unique identifier or delimiter to the file name. -> resolved 6. Implement a retry count mechanism. -> resolved 7. Ensure logs from functions like __alert() are also captured. 8. Allows selecting wheter to reboot or reload after saving the log. -> resolved
On top of the existing functionality: 1. Added the ability to record the time taken to save the log into a file. 2. Improved code readability. 3. Minimized the use of global variables. 4. Added functionality to read logs saved in a file.
| @@ -0,0 +1,57 @@ | |||
| /**************************************************************************** | |||
| * | |||
| * Copyright 2022 Samsung Electronics All Rights Reserved. | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2022 -> 2025.
Apply it to other new files as well.
os/kernel/crashlog_writer/Kconfig
Outdated
| default y | ||
| ---help--- | ||
| Controls whether compression is applied. | ||
| if the value is 0 compression is not performed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should be n instead of 0 since it's a boolean value.
| if (ret < 0) { | ||
| lldbg("read failed\n"); | ||
| free(compressed_buf); | ||
| return -1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can use ERROR instead of -1. OK for 0.
// defined in <sys/types.h>
#define ERROR -1
#define OK 0| static int g_start_to_save = 0; | ||
| static int g_crash_log_index = 0; | ||
| static char g_filename[MAX_FILENAME_LEN]; | ||
| #ifndef REBOOT_AFTER_LOG_SAVE |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CONFIG_ is missing
| static int is_valid_filename(const char *name, int *out_number) | ||
| { | ||
| char expected_prefix[16]; | ||
| snprintf(expected_prefix, sizeof(expected_prefix), "crashlog_"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please define and use prefix value
#define XXX_PREFIX "crashlog_"
| goto reboot_board; | ||
| } | ||
| #endif | ||
| #ifdef CONFIG_CRASH_LOG_SAVE |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use defined values, not hard-coded values for better readability.
#define XXXX_ENABLE 1
#define XXXX_DISABLE 0
| * Saves the crash log to a file. | ||
| * If the flag is 1, the log is saved in compressed form; if it is 0, it is saved uncompressed. | ||
| *************************************************************************************/ | ||
| char *save_crash_log(int flag) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If flag is used for compression only, we'd better to change it to bool compression.
If there will be more options for logging, we can support this with flag setting like below.
For examples,
#define FLAGS_COMPRESS (1 << 0)
#define FLAGS_XXXXX (1 << 1)
caller
flag |= FLAGS_COMPRESS;
save_crash_log(flag);
save_crash_log(int flag)
{
if (sem->flags & FLAGS_COMPRESS) {
ret = crash_log_compress();
} else {
ret = crash_log_to_file();
}
}
| char buf[100]; | ||
| #ifdef CONFIG_COMPRESSION_FLAG | ||
| snprintf(buf, sizeof(buf), "C: %d -> %d ", log_size, ret); | ||
| write(fd, buf, strlen(buf)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add result checking and error handling.
os/arch/arm/src/armv7-a/arm_assert.c
Outdated
| #ifdef CONFIG_CRASH_LOG_SAVE | ||
| #ifdef CONFIG_BINMGR_RECOVERY |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's check CONFIG_CRASH_LOG_SAVE only here.
you already made dependency BINMGR_RECOVERY
| decompress_block(buf, &tmp_buf_size, compressed_buf, &compressed_buf_size); | ||
| free(compressed_buf); | ||
| return tmp_buf_size; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we need to remove log file after read
| #ifdef CONFIG_COMPRESSION_FLAG | ||
| save_crash_log(1); | ||
| #else | ||
| save_crash_log(0); | ||
| #endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-
If we select compress or not using CONFIG_COMPRESSION_FLAG, we don't need to have dynamic check and branch compress or not.
but, if it is for checking memory not enough state, we need to have branch dynamically. -
and binary manager don't need to know about commpress or not, Let's move these into
save_crash_log
void save_crash_log()
{
#ifdef CONFIG_CRASH_LOG_COMPRESS
/* check memory largest chunk */
if (memory enough) {
/* compress log */
/* saving compressed log into fs */
}
#ifdef CONFIG_CRASH_LOG_SUPPORT_MEMORY_FULL
else {
/* just saving log into fs */
}
#endif
#else
/* just saving log into fs */
#endif
}
lib/libc/stdio/lib_lowoutstream.c
Outdated
| DEBUGASSERT(this); | ||
| #ifdef __KERNEL__ | ||
| #ifdef CONFIG_CRASH_LOG_SAVE | ||
| crash_log_to_buffer(ch); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- This feature covers the storage of all logs output in lldbg as well as crash logs
- This feature supports log saving to fs with compress.
How about module naming like ll_log_dump?
os/arch/arm/src/armv7-a/arm_assert.c
Outdated
| #ifdef CONFIG_BINMGR_RECOVERY | ||
| if (IS_FAULT_IN_USER_SPACE(asserted_location)) { | ||
| /* start assert log saving */ | ||
| set_store_to_buffer_flag(1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the fault handler start point might not be here. like arm_dataabort.c
the fault function also have log, the info matters
so in my opinion, we need to set default save on, and we need to stop and start between specific section menually
1. Refactored function and config names for consistency. 2. Updated log file naming convention. 3. Added functionality to read the most recent log file.
lib/libc/stdio/lib_lowoutstream.c
Outdated
| #ifdef __KERNEL__ | ||
| #ifdef CONFIG_CRASH_LOG_SAVE |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about below
#if defined(__KERNEL__) && defined(CONFIG_CRASH_LOG_SAVE)
void crash_log_to_buffer(ch);
#else
#define crash_log_to_buffer(ch) (void)
This makes it possible to specify in the api header that it can only be used in kernel.
The contents of os/kernel/crash_log have been moved to os/kernel/log_dump
| void lowlog_dump_init_buf() | ||
| { | ||
| for (int i = 0; i < CONFIG_LOWLOG_DUMP_BUF_SIZE; i++) { | ||
| g_lowlog[i] = '\0'; | ||
| } | ||
| g_lowlog_index = 0; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we need this? the bss is already 0.
if clear is needed, let's do in save to flash
| #endif | ||
| #endif | ||
| return OK; | ||
| } No newline at end of file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add end of line
| *************************************************************************************/ | ||
| static int lowlog_dump_save_uncomp(char *filenm) | ||
| { | ||
| lldbg("\n\n\n===================================crash log file saving start==========================================\n\n\n"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the log is info, Let's replace to ldpllvdbg
| char new_filename[MAX_FILENAME_LEN]; | ||
| int ret = lowlog_dump_get_next_filename(new_filename); | ||
| if (ret < 0) { | ||
| lldbg("get_next_filename() failed\n"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's replace ldplldbg
| static int lowlog_dump_get_next_filename(char *new_filename) | ||
| { | ||
| DIR *dir = opendir(DIR_PATH); | ||
| if (!dir) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the coding rule indentation Tab Size:4
…nfig - Removed lowlog_dump_set_flag.c - Added lowlog_dump_pause.c and lowlog_dump_resume.c - Redesigned logging behavior: lldbg logs between pause/resume are no longer saved - Removed retry count config - Replaced with CONFIG_LOWLOG_DUMP_MAX_FILES
All lldbg() calls have been updated to ldpllvdbg() Added TODO comments where further improvements or context handling may be needed.
| #ifdef CONFIG_PAGING | ||
| uint32_t *arm_dataabort(uint32_t *regs, uint32_t dfar, uint32_t dfsr) | ||
| { | ||
| { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please revert unnecessary change
| } else { | ||
| asserted_location = kernel_assert_location; | ||
| } | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please revert unnecessary change
| { | ||
| { | ||
| #ifdef CONFIG_LOWLOG_DUMP | ||
| lowlog_dump_set_store_flag(1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it looks missed remove, pelease check
| *************************************************************************************/ | ||
| void lowlog_dump_pause(void) | ||
| { | ||
| ldpllvdbg("\n\n\n==========================================================TO THIS!!==========================================================\n\n\n\n"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what's mean TO THIS???
| { | ||
| { | ||
| #ifdef CONFIG_LOWLOG_DUMP | ||
| lowlog_dump_set_store_flag(1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we need this here?
os/kernel/log_dump/lowlog_dump.h
Outdated
| /**************************************************************************** | ||
| * Function Prototypes | ||
| ****************************************************************************/ | ||
| int lowlog_dump_get_retry_count(void); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it looks not be removed.
os/kernel/log_dump/lowlog_dump.h
Outdated
| /**************************************************************************** | ||
| * Function Prototypes | ||
| ****************************************************************************/ | ||
| int lowlog_dump_get_retry_count(void); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it looks not removed.
os/arch/arm/src/armv7-a/arm_assert.c
Outdated
| if (IS_FAULT_IN_USER_SPACE(asserted_location)) { | ||
| /* Recover user fault through binary manager */ | ||
| binary_manager_recover_userfault(); | ||
| state = NORMAL_STATE; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please revert unnecessary change
Remove unnecessary code
| #include <stdint.h> | ||
| #include <stdlib.h> | ||
| #include <unistd.h> | ||
| #include <string.h> | ||
| #include <errno.h> | ||
| #include <debug.h> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove unnecessary including header
| #ifdef CONFIG_LOWLOG_DUMP | ||
| lowlog_dump_save(); | ||
| #ifdef CONFIG_LOWLOG_DUMP_REBOOT | ||
| binary_manager_reset_board(REBOOT_SYSTEM_BINARY_RECOVERYFAIL); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reboot Reason should not be overwritten here.
in the time, we already writed reason reason about cause of crash.
/* Do not overwrite reboot reason here */
boardctl(BOARDIOC_RESET, EXIT_SUCCESS);| if (lowlog_dump_get_store_flag() && g_lowlog_index < CONFIG_LOWLOG_DUMP_BUF_SIZE) { | ||
| g_lowlog[g_lowlog_index++] = ch; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the previous review, we decided to turn on the log save from the start of booting.
this is because we need to call the start function to all asset occurrence codes in order to turn on log storage in case of asset occurrence.
However, for this to work properly, the g_lowlog buffer must be implemented as a ring buffer.
This is already full due to boot log, so it will not be able to save the assert log.
| if (lowlog_dump_get_store_flag() && g_lowlog_index < CONFIG_LOWLOG_DUMP_BUF_SIZE) { | |
| g_lowlog[g_lowlog_index++] = ch; | |
| } | |
| if (lowlog_dump_get_store_flag()) { | |
| g_lowlog[g_lowlog_tail] = ch; | |
| g_lowlog_tail = (g_lowlog_tail + 1) & BUFFER_MASK; | |
| if (g_lowlog_tail == g_lowlog_head) { | |
| g_lowlog_head = (g_lowlog_head + 1) & BUFFER_MASK; | |
| } | |
| } |
| void lowlog_dump_init() | ||
| { | ||
| lowlog_dump_init_buf(); | ||
| lowlog_dump_init_flag(); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the function is not called anywhere
If it is unnecessary, please remove.
| ldpllvdbg("most_recent_file_name is %s\n",most_recent_file_name); | ||
| lowlog_dump_read(most_recent_file_name, buf, buf_size); | ||
| return OK; | ||
| } No newline at end of file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please add last line
| int pre_filename_comp_len = strlen(PRE_FILENAME_COMP); | ||
| int pre_filename_uncomp_len = strlen(PRE_FILENAME_UNCOMP); | ||
| int name_len = strlen(name); | ||
| if (name_len > pre_filename_comp_len && !strncmp(name, PRE_FILENAME_COMP, pre_filename_comp_len)) { | ||
| for (int i = pre_filename_comp_len; i < name_len; i++) { | ||
| if (!isdigit(name[i])) { | ||
| return ERROR; | ||
| } | ||
| } | ||
| *out_number = atoi(name + pre_filename_comp_len); | ||
| return OK; | ||
| } | ||
| else if (name_len > pre_filename_uncomp_len && !strncmp(name, PRE_FILENAME_UNCOMP, pre_filename_uncomp_len)) { | ||
| for (int i = pre_filename_uncomp_len; i < name_len; i++) { | ||
| if (!isdigit(name[i])) { | ||
| return ERROR; | ||
| } | ||
| } | ||
| *out_number = atoi(name + pre_filename_uncomp_len); | ||
| return OK; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#ifdef CONFIG_LOWLOG_DUMP_COMPRESS
ret = lowlog_dump_compress_and_save(filenm);
#else
ret = lowlog_dump_save_uncomp(filenm);
#endifIf compression is determined by CONFIG_LOWLOG_DUMP_COMPRESS, we do not need to check both of these here.
| int pre_filename_comp_len = strlen(PRE_FILENAME_COMP); | |
| int pre_filename_uncomp_len = strlen(PRE_FILENAME_UNCOMP); | |
| int name_len = strlen(name); | |
| if (name_len > pre_filename_comp_len && !strncmp(name, PRE_FILENAME_COMP, pre_filename_comp_len)) { | |
| for (int i = pre_filename_comp_len; i < name_len; i++) { | |
| if (!isdigit(name[i])) { | |
| return ERROR; | |
| } | |
| } | |
| *out_number = atoi(name + pre_filename_comp_len); | |
| return OK; | |
| } | |
| else if (name_len > pre_filename_uncomp_len && !strncmp(name, PRE_FILENAME_UNCOMP, pre_filename_uncomp_len)) { | |
| for (int i = pre_filename_uncomp_len; i < name_len; i++) { | |
| if (!isdigit(name[i])) { | |
| return ERROR; | |
| } | |
| } | |
| *out_number = atoi(name + pre_filename_uncomp_len); | |
| return OK; | |
| } | |
| #ifdef CONFIG_LOWLOG_DUMP_COMPRESS | |
| #define PRE_FILENAME "lowlog_dump_comp" | |
| #else | |
| #define PRE_FILENAME "lowlog_dump" | |
| #endif | |
| int pre_filename_len = strlen(PRE_FILENAME); | |
| int name_len = strlen(name); | |
| if (name_len > pre_filename_len && !strncmp(name, PRE_FILENAME, pre_filename_len)) { | |
| for (int i = pre_filename_len; i < name_len; i++) { | |
| if (!isdigit(name[i])) { | |
| return ERROR; | |
| } | |
| } | |
| *out_number = atoi(name + pre_filename_len); | |
| return OK; | |
| } |
| #ifdef CONFIG_LOWLOG_DUMP_COMPRESS | ||
| snprintf(tmp, MAX_FILENAME_LEN - path_len - 1, "%s%d", PRE_FILENAME_COMP, max_number + 1); | ||
| #else | ||
| snprintf(tmp, MAX_FILENAME_LEN - path_len - 1, "%s%d", PRE_FILENAME_UNCOMP, max_number + 1); | ||
| #endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please check my above comment
| static int lowlog_dump_save_uncomp(char *filenm) | ||
| { | ||
| ldpllvdbg("\n\n\n===================================crash log file saving start==========================================\n\n\n"); | ||
| char new_filename[MAX_FILENAME_LEN]; | ||
| int ret = lowlog_dump_get_next_filename(new_filename); | ||
| if (ret < 0) { | ||
| ldpllvdbg("get_next_filename() failed\n"); | ||
| return ERROR; | ||
| } | ||
| int fd = open(new_filename, O_WRONLY | O_CREAT | O_TRUNC); | ||
| if (fd < 0) { | ||
| ldpllvdbg("file open failed\n"); | ||
| return ERROR; | ||
| } | ||
| int log_size = write(fd, lowlog_dump_get_buf(), lowlog_dump_get_size()); | ||
| close(fd); | ||
| if (log_size < 0) { | ||
| ldpllvdbg("file write failed\n"); | ||
| return ERROR; | ||
| } | ||
| snprintf(filenm, MAX_FILENAME_LEN, "%s", new_filename); | ||
| ldpllvdbg("file write success, count:%d\n", log_size); | ||
| ldpllvdbg("\n\n\n===========================================crash log file saving end=====================================================\n\n\n"); | ||
| return log_size; | ||
| } | ||
|
|
||
| /************************************************************************************* | ||
| * Name: lowlog_dump_save_comp | ||
| * | ||
| * Description: | ||
| * Saves the compressed log from the buffer to a file. | ||
| *************************************************************************************/ | ||
| static int lowlog_dump_save_comp(char *filenm, unsigned char *compressed_buf, unsigned int compressed_buf_size) | ||
| { | ||
| ldpllvdbg("\n\n================================================================compress file write start===========================================================\n\n"); | ||
| char new_filename[MAX_FILENAME_LEN]; | ||
| if (compressed_buf == NULL) { | ||
| return ERROR; | ||
| } | ||
| int ret = lowlog_dump_get_next_filename(new_filename); | ||
| ldpllvdbg("filename is %s\n", new_filename); | ||
| if (ret < 0) { | ||
| ldpllvdbg("get_next_filename() failed\n"); | ||
| return ERROR; | ||
| } | ||
| int fd = open(new_filename, O_WRONLY | O_CREAT | O_TRUNC); | ||
| if (fd < 0) { | ||
| ldpllvdbg("file open failed\n"); | ||
| return ERROR; | ||
| } | ||
| ret = write(fd, compressed_buf, compressed_buf_size); | ||
| if (ret < 0) { | ||
| ldpllvdbg("file write failed\n"); | ||
| close(fd); | ||
| return ERROR; | ||
| } | ||
| close(fd); | ||
| snprintf(filenm, MAX_FILENAME_LEN, "%s", new_filename); | ||
| ldpllvdbg("write count: %d\n", ret); | ||
| ldpllvdbg("\n\n==========================================================compress file write end===========================================================\n\n"); | ||
| return ret; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the two function are almost same
we can reduce duplicated code like below
static int lowlog_dump_save_to_file(char *log_buf, size_t size)
{
/* file save codes */
}
#ifdef CONFIG_LOWLOG_DUMP_COMPRESS
static int lowlog_dump_save_to_file_with_comp(char *log_buf, size_t size)
{
/* compress codes */
return lowlog_dump_save_to_file(compressed_buf, compressed_buf_size);
}
#endif
#ifdef CONFIG_LOWLOG_DUMP_COMPRESS
ret = lowlog_dump_save_to_file_with_comp(lowlog_dump_get_buf(), lowlog_dump_get_size());
#else
ret = lowlog_dump_save_to_file(lowlog_dump_get_buf(), lowlog_dump_get_size());
#endif| static int lowlog_dump_compress_and_save(char *filenm) | ||
| { | ||
| ldpllvdbg("\n\n=====================================================compress start=====================================================\n\n"); | ||
| int malloc_size = lowlog_dump_get_size() / 3; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how did you decide compress buffer malloc size?
| #ifdef CONFIG_LOWLOG_DUMP_RECORD_TIME | ||
| clock_t end = clock(); | ||
| double elapsed_time = (double)(end - start) / CLOCKS_PER_SEC; | ||
| lldbg("\n\nElapsed time: %.6f seconds\n\n", elapsed_time); | ||
| char buf[MAX_FILENAME_LEN]; | ||
| snprintf(buf, sizeof(buf), "%s/result", DIR_PATH); | ||
|
|
||
| int fd = open(buf, O_CREAT | O_WRONLY | O_APPEND); | ||
| if (fd < 0) { | ||
| return ERROR; | ||
| } | ||
| //TODO : The number of snprintf and write calls should be reduced. | ||
| //TODO : add result checking and error handling about snprintf and write. | ||
| //TODO : result size should be limited. | ||
| #ifdef CONFIG_LOWLOG_DUMP_COMPRESS | ||
| snprintf(buf, sizeof(buf), "C: %d -> %d ", log_size, ret); | ||
| write(fd, buf, strlen(buf)); | ||
| #else | ||
| snprintf(buf, sizeof(buf), "U: %d ", ret); | ||
| write(fd, buf, strlen(buf)); | ||
| #endif | ||
| snprintf(buf, sizeof(buf), "in %.6fs", elapsed_time); | ||
| write(fd, buf, strlen(buf)); | ||
| snprintf(buf, sizeof(buf), " (%s)\n", filenm); | ||
| write(fd, buf, strlen(buf)); | ||
| close(fd); | ||
| #endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This appears to be a debugging code for calculating log storage time.
If yes, please remove this code.
5fff51f to
c618e14
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added crash log flash save in os kernel crashlog writer module, this change is good to merge.
Developed a new feature to store logs during assert situations. It only operates when a crash occurs in the user space.
The following modifications are required: