Skip to content

Conversation

@Kimhyunjong121
Copy link

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.
  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.
  5. Add a unique identifier or delimiter to the file name.
  6. Implement a retry count mechanism.
  7. Ensure logs from functions like __alert() are also captured.

Comment on lines 126 to 134
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];
Copy link
Contributor

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);
Copy link
Contributor

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?

#ifdef CONFIG_BINMGR_RECOVERY
if (IS_FAULT_IN_USER_SPACE(asserted_location)) {
/* start assert log saving */
set_assert_situation();
Copy link
Contributor

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?

Comment on lines 350 to 355
set_notassert_situation();
assert_log_to_file();
assert_log_compress();
compressed_assert_log_to_file();
compressed_assert_log_read();
decompress_and_print();
Copy link
Contributor

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()

Comment on lines 712 to 720
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");

}
Copy link
Contributor

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.

Copy link
Author

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.

  1. 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

  1. 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);
Copy link
Contributor

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.

Copy link
Contributor

@ewoodev ewoodev left a 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

return -1;
}
lldbg("file open success\n");
int log_size=write(fd,assert_log,strlen(assert_log));
Copy link
Contributor

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;
	}

int ret=write(fd,compressed_buf,compressed_buf_size);
if(ret<0){
lldbg("file write failed\n");
return -1;
Copy link
Contributor

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.

}
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);
Copy link
Contributor

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.

}
int set_assert_situation(){
lldbg("\n\n\n===============================FROM THIS, lldbg LOG WILL BE SAVED!!================================\n\n\n\n");
assert_situation=1;
Copy link
Contributor

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;

*/
int lowvsyslog(int priority, FAR const char *format, va_list ap);


Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary file changes

@Kimhyunjong121 Kimhyunjong121 force-pushed the 7_24 branch 3 times, most recently from dba5e00 to 8cfcc29 Compare July 30, 2025 04:43
@Kimhyunjong121 Kimhyunjong121 changed the title os/kernel/log_dump: Add crash log flash save os/kernel/crashlog_writer: Add crash log flash save Jul 30, 2025
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.
Copy link
Contributor

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.

default y
---help---
Controls whether compression is applied.
if the value is 0 compression is not performed.
Copy link
Contributor

@seokhun-eom24 seokhun-eom24 Jul 30, 2025

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;
Copy link
Contributor

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
Copy link
Contributor

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_");
Copy link
Contributor

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
Copy link
Contributor

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)
Copy link
Contributor

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));
Copy link
Contributor

@jeongarmy jeongarmy Jul 31, 2025

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.

Comment on lines 617 to 618
#ifdef CONFIG_CRASH_LOG_SAVE
#ifdef CONFIG_BINMGR_RECOVERY
Copy link
Contributor

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;
}
Copy link
Contributor

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

Comment on lines 355 to 359
#ifdef CONFIG_COMPRESSION_FLAG
save_crash_log(1);
#else
save_crash_log(0);
#endif
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. 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.

  2. 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
}

DEBUGASSERT(this);
#ifdef __KERNEL__
#ifdef CONFIG_CRASH_LOG_SAVE
crash_log_to_buffer(ch);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. This feature covers the storage of all logs output in lldbg as well as crash logs
  2. This feature supports log saving to fs with compress.

How about module naming like ll_log_dump?

#ifdef CONFIG_BINMGR_RECOVERY
if (IS_FAULT_IN_USER_SPACE(asserted_location)) {
/* start assert log saving */
set_store_to_buffer_flag(1);
Copy link
Contributor

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.
Comment on lines 82 to 83
#ifdef __KERNEL__
#ifdef CONFIG_CRASH_LOG_SAVE
Copy link
Contributor

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
Comment on lines 67 to 73
void lowlog_dump_init_buf()
{
for (int i = 0; i < CONFIG_LOWLOG_DUMP_BUF_SIZE; i++) {
g_lowlog[i] = '\0';
}
g_lowlog_index = 0;
}
Copy link
Contributor

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
Copy link
Contributor

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");
Copy link
Contributor

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");
Copy link
Contributor

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) {
Copy link
Contributor

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)
{
{
Copy link
Contributor

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;
}

Copy link
Contributor

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);
Copy link
Contributor

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");
Copy link
Contributor

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);
Copy link
Contributor

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?

/****************************************************************************
* Function Prototypes
****************************************************************************/
int lowlog_dump_get_retry_count(void);
Copy link
Contributor

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.

/****************************************************************************
* Function Prototypes
****************************************************************************/
int lowlog_dump_get_retry_count(void);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it looks not removed.

if (IS_FAULT_IN_USER_SPACE(asserted_location)) {
/* Recover user fault through binary manager */
binary_manager_recover_userfault();
state = NORMAL_STATE;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please revert unnecessary change

Comment on lines +30 to +35
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <debug.h>
Copy link
Contributor

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);
Copy link
Contributor

@ewoodev ewoodev Aug 25, 2025

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);

Comment on lines +100 to +102
if (lowlog_dump_get_store_flag() && g_lowlog_index < CONFIG_LOWLOG_DUMP_BUF_SIZE) {
g_lowlog[g_lowlog_index++] = ch;
}
Copy link
Contributor

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.

Suggested change
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;
}
}

Comment on lines +57 to +61
void lowlog_dump_init()
{
lowlog_dump_init_buf();
lowlog_dump_init_flag();
}
Copy link
Contributor

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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add last line

Comment on lines +60 to +80
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;
}
Copy link
Contributor

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);
#endif

If compression is determined by CONFIG_LOWLOG_DUMP_COMPRESS, we do not need to check both of these here.

Suggested change
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;
}

Comment on lines +146 to +149
#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
Copy link
Contributor

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

Comment on lines +161 to +221
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;
}
Copy link
Contributor

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;
Copy link
Contributor

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?

Comment on lines 290 to 313
#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
Copy link
Contributor

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.

Copy link
Contributor

@samsung-singh samsung-singh left a 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants