init进程调试

来自个人维基
跳转至: 导航搜索

调试的原因很简单,就是出现问题了:把一个进程的启动顺序提前,但实际却启动不起来,如:

on fs_property:ro.mount.fs=EXT4
    start my_daemon

on init
start my_daemon

于是要想办法把log打印出来。但在开机前期,log系统、文件系统都还未就绪,因此这不是一个简单的事情。

于是想先把log打印到一个buffer中,待系统启动后再通过通用的log系统打印出来:

#define MAX_LEN (1024*1024*10)
char g_kBuffer[MAX_LEN] = {"head\n"};
int g_occupiedByte = 5;
void logToBuffer(char *format, ... ) {
    char *m_str = g_kBuffer+g_occupiedByte;    
    va_list arg_ptr;
    va_start(arg_ptr, format);
    vsnprintf(m_str, MAX_LEN-g_occupiedByte-1, format, arg_ptr); //vsprintf    
    va_end(arg_ptr);
    if(g_kBuffer[strlen(g_kBuffer)-1] != '\n') {
        strncat(g_kBuffer, "\n", MAX_LEN);
    }
    g_occupiedByte = strlen(g_kBuffer);    
}

//受log系统打印长度限制,需分段打印
void printKBuffer() {
	#define KLOG_MAX_LEN 300
	int i = 0;
	char tmpStr[KLOG_MAX_LEN];
	for(i = 0; i < strlen(g_kBuffer);) {
		strncpy(tmpStr, (char*)(g_kBuffer+i), KLOG_MAX_LEN);
		klog_write(1, "logyfish>|%s\n", tmpStr);
		i+=KLOG_MAX_LEN;
	}	
}

void* logDaemonTrd(void *ptr) {
    //sleep(20);
    while(1) {
        klog_write(1, "\n======================logyfish start=========================\n");
        printKBuffer();//klog_write(1, ">|%s\n", g_kBuffer);
		klog_write(1, "\n======================logyfish end=========================\n");	
        sleep(3);
    }

    return NULL;
}

然后再在init的main中启动一个线程用来打印log:

    //start:logyfish
    pthread_t ssdTrd = 0;
    pthread_create(&ssdTrd, NULL, logDaemonTrd, NULL);
    //end

最后再在需要的地方加上log,如 execute_one_command和 service_start函数.

打印log如下:

<4>[   55.130331] (2)[81:init]======================logyfish start=========================
<4>[   55.130444] (2)[81:init]logyfish>|head
<4>[   55.130450] (2)[81:init]processing action 0xa43ba8 (early-init)
<4>[   55.130457] (2)[81:init]command r=0 ' write /proc/1/oom_adj -16'
<4>[   55.130464] (2)[81:init]command r=0 ' setcon u:r:init:s0'
<4>[   55.130470] (2)[81:init]starting 'ueventd'
<4>[   55.130475] (2)[81:init]==>ueventd ruunning
<4>[   55.130481] (2)[81:init]command r=0 ' start ueventd'
<4>[   55.130487] (2)[81:init]command r=0 ' mkdir /mnt 0775 root system'
<4>[   55.130494] (2)[81:init]processing action 0xa59430 (early-init)
<4>[   55.130500] (2)[81:init]processing action 0xa5a380 (e
<4>[   55.130600] (2)[81:init]logyfish>|arly-init)
<4>[   55.130606] (2)[81:init]command r=0 ' mkdir /protect_f 0771 system system'
<4>[   55.130613] (2)[81:init]command r=0 ' mkdir /protect_s 0771 system system'
<4>[   55.130621] (2)[81:init]processing action 0xa5bed0 (wait_for_coldboot_done)
<4>[   55.130628] (2)[81:init]command r=0 ''
<4>[   55.130633] (2)[81:init]processing action 0xa5bf18 (keychord_init)
<4>[   55.130640] (2)[81:init]command r=0 ''
<4>[   55.130645] (2)[81:init]processing action 0xa5bf60 (console_init)
<4>[   55.130652] (2)[81:init]command r=0 ''
<4>[   55.130657] (2)[81:init]proce
<4>[   55.130751] (2)[81:init]logyfish>|ssing action 0xa372d0 (init)
<4>[   55.130758] (2)[81:init]command r=0 ' write /proc/self/coredump_filter 39'
<4>[   55.130765] (2)[81:init]processing action 0xa43e48 (init)
<4>[   55.130772] (2)[81:init]cannot find '/system/bin/my_daemon', disabling 'my_daemon'
<4>[   55.130780] (2)[81:init]command r=0 ' start my_daemon'
<4>[   55.130786] (2)[81:init]command r=0 ' sysclktz 0'
<4>[   55.130792] (2)[81:init]command r=0 ' loglevel 6'
...
<4>[   55.132748] (2)[81:init]processing action 0xa43708 (fs_property:ro.mount.fs=EXT4)
<4>[   55.132755] (2)[81:init]cannot find '/system/bin/my_daemon', disabling 'my_daemon'
<4>[   55.132763] (2)[81:init]command r=0 ' start my_daemon'
<4>[   55.132770] (2)[81:init]processing action 0xa44c38 (fs_property:ro.mount.fs=EXT4)
...

cannot find '/system/bin/my_daemon', disabling 'my_daemon' ==>可知是此时/system分区还未就绪导致启动失败,同时这种情况下系统还会自动给 service加入 DISABLED属性:

    if (stat(svc->args[0], &s) != 0) {
        logToBuffer("cannot find '%s', disabling '%s'\n", svc->args[0], svc->name);
        svc->flags |= SVC_DISABLED;
        return;
    }

所以现在知道解决方案了,就是要确保在对应可执行文件所在文件系统就绪后再启动 service:

on post-fs-data
    start my_daemon

问题顺势而解!