博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
函数分析AndroidInitProcess分析心得(2)
阅读量:5861 次
发布时间:2019-06-19

本文共 4811 字,大约阅读时间需要 16 分钟。

上班之余抽点时间出来写写博文,希望对新接触的朋友有帮助。今天在这里和大家一起学习一下函数分析

//\system\core\init\init_parser.cint lookup_keyword(const char *s){    switch (*s++) {    case 'c':    if (!strcmp(s, "opy")) return K_copy;        if (!strcmp(s, "apability")) return K_capability;        if (!strcmp(s, "hdir")) return K_chdir;        if (!strcmp(s, "hroot")) return K_chroot;        if (!strcmp(s, "lass")) return K_class;        if (!strcmp(s, "lass_start")) return K_class_start;        if (!strcmp(s, "lass_stop")) return K_class_stop;        if (!strcmp(s, "lass_reset")) return K_class_reset;        //......    }    return K_UNKNOWN;}

    由此段程序代码可以发明此函数会根据存入的符字串先由符字串的第一个符字做分类, 再去比拟后之的符字去回传相对应的K_xxx.后之再将keyword传入kw_is作断判,Google在这里的断判计划kw_is会利用macro而不是用一般的函数去实作, 一是因为这个断判动作只有单纯的做比对,另外一点就是会少一次functioncall stack的效能以快加执行速度.

//system\core\init\init_parser.c#define kw_is(kw, type) (keyword_info[kw].flags & (type))

    这里会发明是用keyword_info数组中的元素所带出来的flags跟type作&比拟.

//system\core\init\init_parser.c#define KEYWORD(symbol, flags, nargs, func) \    [ K_##symbol ] = { #symbol, func, nargs + 1, flags, },struct {    const char *name;    int (*func)(int nargs, char **args);    unsigned char nargs;    unsigned char flags;} keyword_info[KEYWORD_COUNT] = {    [ K_UNKNOWN ] = { "unknown", 0, 0, 0 },#include "keywords.h"};//system\core\init\keywords.h//...    KEYWORD(capability,  OPTION,  0, 0)    KEYWORD(chdir,       COMMAND, 1, do_chdir)    KEYWORD(chroot,      COMMAND, 1, do_chroot)    KEYWORD(class,       OPTION,  0, 0)    KEYWORD(class_start, COMMAND, 1, do_class_start)    KEYWORD(class_stop,  COMMAND, 1, do_class_stop)    KEYWORD(class_reset, COMMAND, 1, do_class_reset)    KEYWORD(console,     OPTION,  0, 0)//....

    由面上便可以晓得keyword_info是一个Mappingtable. 个一每lookup_keyword 函数所回传的keyword K_xxx对应一个函数do_xxx.

        因此便可以再从parse_config函数中的呼叫lookup_keyword继承分析下去.

// system\core\init\init_parser.cint kw = lookup_keyword(args[0]);if (kw_is(kw, SECTION)) {      state.parse_line(&state, 0, 0);      parse_new_section(&state, kw, nargs, args);} else {     state.parse_line(&state, nargs, args);}

    由之前针对lookup_keyword和kw_is的分析就能够晓得, 这里是要从init.rc中捞出keyword再利用kw_is的断判来做不同parser式方. 由面上的程序代码可以晓得, 只有在keyword_infomapping table中有SECTION flag, 才会有新的list. 而在(android4.2)现在的本版中从keywords.h有所的KEYWORD可晓得, 有SECTIONflag对应到的符字只有import, on, service. 撇开import符字是用来作似类include的动作以外,on跟service就是用来立建之前所提的actionlist和service list. 接下来分析parse_new_section函数

    每日一道理
这浓浓的母爱使我深深地认识到:即使你是一只矫健的雄鹰,也永远飞不出母爱的长空;即使你是一条扬帆行驶的快船,也永远驶不出母爱的长河!在人生的路上不管我们已走过多远,还要走多远,我们都要经过母亲精心营造的那座桥!
//system\core\init\init_parser.cvoid parse_new_section(struct parse_state *state, int kw,                       int nargs, char **args){    printf("[ %s %s ]\n", args[0],           nargs > 1 ? args[1] : "");    switch(kw) {    case K_service:        state->context = parse_service(state, nargs, args);        if (state->context) {            state->parse_line = parse_line_service;            return;        }        break;    case K_on:        state->context = parse_action(state, nargs, args);        if (state->context) {            state->parse_line = parse_line_action;            return;        }        break;    case K_import:        parse_import(state, nargs, args);        break;    }    state->parse_line = parse_line_no_op;}

    由于在执行流程分析中, execute_one_command函数就只有用来执行action list面上的command,所以就从parse_action函数来分析.

//system\core\init\init_parser.cstatic void *parse_action(struct parse_state *state, int nargs, char **args){    struct action *act;    if (nargs < 2) {        parse_error(state, "actions must have a trigger\n");        return 0;    }    if (nargs > 2) {        parse_error(state, "actions may not have extra parameters\n");        return 0;    }    act = calloc(1, sizeof(*act));    act->name = args[1];    list_init(&act->commands);    list_add_tail(&action_list, &act->alist);        /* XXX add to hash */    return act;}

    由面上的程序代码可以晓得, action list就是由一串act 元素所立建起来的linkedlist. 一旦action list有了新的act 元素, 接下来就执行parse_line_action函数

//system\core\init\init_parser.cstatic void parse_line_action(struct parse_state* state, int nargs, char **args){    struct command *cmd;    struct action *act = state->context;    int (*func)(int nargs, char **args);    int kw, n;    if (nargs == 0) {        return;    }    kw = lookup_keyword(args[0]);    if (!kw_is(kw, COMMAND)) {        parse_error(state, "invalid command '%s'\n", args[0]);        return;    }    n = kw_nargs(kw);    if (nargs < n) {        parse_error(state, "%s requires %d %s\n", args[0], n - 1,            n > 2 ? "arguments" : "argument");        return;    }    cmd = malloc(sizeof(*cmd) + sizeof(char*) * nargs);    cmd->func = kw_func(kw);    cmd->nargs = nargs;    memcpy(cmd->args, args, sizeof(char*) * nargs);    list_add_tail(&act->commands, &cmd->clist);}

文章结束给大家分享下程序员的一些笑话语录: 一位程序员去海边游泳,由于水性不佳,游不回岸了,于是他挥着手臂,大声求.救:“F1,F1!”

转载地址:http://lxunx.baihongyu.com/

你可能感兴趣的文章
七、Shell printf 命令
查看>>
Linux Redis集群搭建与集群客户端实现
查看>>
Redis入门
查看>>
LeetCode: Populating Next Right Pointer in Each Node
查看>>
mongodb-CURD
查看>>
OpenLayers学习笔记(一)—在线加载谷歌影像地图&离线加载本地瓦片地图
查看>>
【uva 1349】Optimal Bus Route Design(图论--网络流 二分图的最小权完美匹配)
查看>>
UOJ #58 糖果公园
查看>>
HDU 1114 【完全背包裸题】
查看>>
将字符串切割成数组 componentsSeparatedByString
查看>>
CentOS网卡配置
查看>>
[Shell] echo/输出 中引用命令
查看>>
实验6 Bezier曲线生成
查看>>
python 面向对象三大特性--多态
查看>>
使用FreePic2Pdf导出书签至Word建立层级目录——快速初始化Word笔记本目录
查看>>
OpenCL入门:(一:Intel核心显卡OpenCL环境搭建)
查看>>
spring学习--4
查看>>
Python的从头再来
查看>>
Android中的长度单位详解
查看>>
keras
查看>>