2021/03/17

C 將 stdout 轉給 console

daemon 的除錯訊息被殼層吃掉的時候, 將訊息丟到 console 可以方便除錯, 如果是每次呼叫 debug 時都 openfile 和 closefile 會有點浪費資源, 所以直接將 stdout 轉給 console, 就能繼續用 printf 來送出除錯訊息了.

做法就是開個 file handler 給 console, 然後重新將 stdout 設定給 console 的 file handler. 範例程式如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
#include <stdio.h>
int main()
{
	FILE *stdout_bk;
	FILE *fpout = fopen("/dev/console" ,"w" );
	stdout_bk = stdout;
	printf("printf not to console\n");
	stdout = fpout;
	printf("printf to console\n");
	stdout = stdout_bk;
	return 0;
}


做成 MACRO

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
#ifdef AIMDBG
#undef AIMDBG
#endif
#define AIMDBG(fmt,...) \
do { \
    FILE *console = fopen("/dev/console" ,"w" ); \
    if (console) { \
        fprintf(console, fmt, __VA_ARGS__); \
        fflush(console); \
        fclose(console); \
    } \
} while(0)


追加 Hexdump

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
static void hexdump (uint8_t* ptr, int len) {
    int i;
    for (i=0; i<len; i++) {
        if (15 == (i % 16)) {
            AIMDBG("%02X\n", ptr[i]);
        }
        else if (7 == (i % 8)) {
            AIMDBG("%02X   ", ptr[i]);
        }
        else {
            AIMDBG("%02X ", ptr[i]);
        }
    }
    AIMDBG("%s", "\n");
}

2021/03/05

快速重製 oom 確認 memory leak 的問題

memory leak 會造成記憶體不足而引發 linux 的 oom kill 機制. 假如有 memory leak 的情況發生, 記憶體應該會被佔用而越來越少, 所以要認或是驗證有沒有解決 memory leak, 最簡單的方式就是寫一隻程式來把記憶體占用, 藉此縮短驗證所需的時間.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
typedef struct S_ROBBER
{
	char occupy[1024];
} C_ROBBER;

void syntax(char *command)
{
	printf("Syntax:\n");
	printf("\t%s mem_request(MB)\n", command);
	printf("\t\t mem_request between 1 and 128\n", command);
}

int main( int argc, char **argv)
{
	int memreq;
	int i, j;
	char *robber[128][1024];
	C_ROBBER *ptr;
	
	if (argc != 2) {
		syntax(argv[0]);
		return 0;
	}
	
	memreq = atoi(argv[1]);
	
	if (memreq < 1 || memreq > 128) {
		syntax(argv[0]);
		return 0;
	}
	
	for (i=0; i<memreq; i++) {
		for (j=0; j<1024; j++) {
			ptr = (C_ROBBER *)malloc(sizeof(C_ROBBER));
			if (ptr)
			{
				robber[i][j] = ptr;
			} else {
				printf("Your system was very very poor!\n");
				break;
			}
		}
		if (j < 1024) {
			break;
		}
	}
	printf("Robber occupy %dMB memory, now.\n", i);
	
	while(1) {
		sleep(3600);
	}
}

這隻程式會根據船進去的參數, 以 MB 為單位, 霸佔記憶體. 最大占用限制 128MB.

一般系統在記憶體不足時會觸發 oom kill, 而強盜程式會是被殺的最大目標, 所以要把 oom kill 機制關閉, 讓系統直接 panic. 指令如下

1
echo 1 > /proc/sys/vm/panic_on_oom

這樣就可以先用強盜程式將記憶體占用到只剩下一點點, 當記憶體不足的情形發生時, 會直接 panic 而不是把強盜砍掉, 就可以大幅度的縮短重製及驗證的時間.