ChkBugReport工具 for Android 5

ChkBugReport 中 bugreport 全部解析 

Main 中 run  函数 -> 调用 mMod.addFile(arg, null, false); -> BugReportModule 中最终调用 private boolean load(InputStream is, boolean partialString secName) 函数:

  

<span style="color:#333333">private boolean load(InputStream is, boolean partial, String secName) throws IOException {
        long t0 = System.currentTimeMillis();
        printOut(1, "Loading input...");
        LineReader br = new LineReader(is);
        String buff;
        Section curSection = null;
        mTimestamp = null;
        int lineNr = 0;
        int skipCount = 5;
        boolean formatOk = partial;
        while (null != (buff = br.readLine())) {
            if (!formatOk) {
                // Sill need file format validation
                // Check if this is a dropbox file
                if (0 == lineNr && buff.startsWith("Process: ")) {
                    return loadFromDopBox(br, buff);
                }

                if (0 == lineNr) {
                    // Not detected yet
                    if (buff.startsWith("==============")) {
                        // Ok, pass through and start processing
                    } else {
                        if (0 == --skipCount) {
                            // give up (simply pass through and let if fail later)
                        } else {
                            // Give another chance
                            continue;
                        }
                    }
                }

                // Verify file format (just a simple sanity check)
                lineNr++;

                if (1 == lineNr && !buff.startsWith("==============")) break;
                if (2 == lineNr && !buff.startsWith("== dumpstate")) break;
                if (3 == lineNr && !buff.startsWith("==============")) break;
                if (4 == lineNr) {
                    formatOk = true;
                }

                // Extract timestamp of crash
                Calendar ts = Util.parseTimestamp(this, buff);
                if (ts != null) {
                    mTimestamp = ts;
                }
            }

            // Parse sections and sub-sections
            if (buff.startsWith("------ ")) {
                // build up file name
                int e = buff.indexOf(" ------");
                if (e >= 0) {
                    String sectionName = buff.substring(7, e);

                    // Workaround for SMAP spamming
                    boolean newSection = true;
                    if (curSection != null && curSection.getName().equals("SMAPS OF ALL PROCESSES")) {
                        if (sectionName.startsWith("SHOW MAP ")) {
                            newSection = false;
                        }
                    }
                    if (newSection) {
                        Section section = new Section(this, sectionName);
                        addSection(section);
                        curSection = section;
                        continue;
                    }
                }
            }

            // Workaround for buggy wallpaper service dump
            int idx = buff.indexOf(SECTION_DIVIDER);
            if (idx > 0) {
                if (curSection != null) {
                    curSection.addLine(buff.substring(0, idx));
                }
                buff = buff.substring(idx);
            }

            if (buff.equals(SECTION_DIVIDER)) {
                // Another kind of marker
                // Need to read the next line
                String sectionName = br.readLine();
                if (sectionName != null) {
                    if ("DUMP OF SERVICE activity:".equals(sectionName)) {
                        // skip over this name, and use the next line as title, the provider thingy
                        sectionName = br.readLine();
                    }
                }
                if (sectionName != null) {
                    Section section = new Section(this, sectionName);
                    addSection(section);
                    curSection = section;
                }
                continue;
            }

            // Add the current line to the current section
            if (curSection == null && partial) {
                // We better not spam the header section, so let's create a fake section
                curSection = new Section(this, secName);
                addSection(curSection);
            }
            if (curSection != null) {
                curSection.addLine(buff);
            } else {
                addHeaderLine(buff);
                mBugReportHeader.add(buff);
            }
        }

        br.close();

        long t1 = System.currentTimeMillis();
        printOut(1, String.format("Loaded in %.2f seconds.", (t1 - t0) / 1000.0f));
        if (!formatOk) {
            throw new IOException("Does not look like a bugreport file!");
        }
        return true;
    }</span>

使用 Section 对象保存。保存对应文件操作:

 

<span style="color:#333333">private void saveSections() throws IOException {
        Chapter ch = new Chapter(getContext(), "Raw data");
        List list = new List();
        ch.add(list);

        for (Section s : mSections) {
            String fn = mDoc.getRelRawDir() + s.getFileName();
            list.add(new Link(mDoc.getRelRawDir() + s.getFileName(), s.getName()));
            FileOutputStream fos = new FileOutputStream(getBaseDir() + fn);
            PrintStream ps = new PrintStream(fos);
            int cnt = s.getLineCount();
            for (int i = 0; i < cnt; i++) {
                ps.println(s.getLine(i));
            }
            ps.close();
            fos.close();
        }

        addChapter(ch);
    }</span>

从HTML报告中Raw data查看:

 

 

 

xml 插件扩展 Load 子标签支持

 Load 扩展标签

<span style="color:#333333">	<load>
		<filter section="DUMP OF SERVICE dropbox" chapterName="DUMP/DUMP OF SERVICE dropbox" infoId="dumpdropboxlog" />
	</load></span>

 

load 标签 filter 子标签中:

  • section 是生成Log对象;
  • chapterName 报告中左侧目录;
  • infoId 筛选Log时从 BugReportModule.java 中获取 Log 的 key。

Section key有哪些

查看 Section 对象,添加 Log 输出,在 HTML 报告查看 Header 中ChkBugReport's log: chkbugreport_log.txt:

从代码中是使用mShortName:

<span style="color:#333333">public void addSection(Section section) {
        mSections.add(section);
        mSectionMap.put(section.getShortName(), section);
    }

    /**
     * Find the Section with the given name,
     *
     * @param name The name of the section
     * @return The Section from the bugreport or null if not found
     */
    public Section findSection(String name) {
        return mSectionMap.get(name);
    }</span>

code 实现

ExtXMLPlugin.java 中扩展loadgenerate 函数等:

<span style="color:#333333">    private Vector<ExtLogData> mLogs = new Vector<ExtLogData>();

    @Override
    public void load(Module mod) {
        // Execute the "load" tag
        XMLNode load = mXml.getChild("load");
        if (load == null) {
            // <load> tag is missing, do nothing.
            return;
        }

        BugReportModule br = (BugReportModule) mod;
        for (XMLNode chTag : load) {
            String tag = chTag.getName();
            if (tag == null) continue;
            if ("filter".equals(tag)) {
                String section = chTag.getAttr("section");
                String chapterName = chTag.getAttr("chapterName");
                String infoId = chTag.getAttr("infoId");
                br.printOut(2, TAG + " section [" + section + "] , chapterName [" + chapterName + "] , infoId [" + infoId + "]");
                if(section == null) continue;
                loadLog(br, section, chapterName, infoId);
            }
        }
    }

    private void loadLog(BugReportModule br, String sectionName, String chapterName, String infoId) {
        Section section = br.findSection(sectionName);
        if (section == null) {
            br.printErr(3, TAG + "Cannot find section [" + sectionName + "] (ignoring)");
            return;
        }

        ExtLogData data = new ExtLogData(br, section, chapterName, infoId);
        mLogs.add(data);
    }

    @Override
    public void generate(Module mod) {
        for (ExtLogData log : mLogs) {
            log.generate();
        }

        // Find the generate tag
        XMLNode gen = mXml.getChild("generate");
        if (gen != null) {
            for (XMLNode chTag : gen) {
                String tag = chTag.getName();
                if (tag == null) continue;
                if ("chapter".equals(tag)) {
                    Chapter ch = mod.findOrCreateChapter(chTag.getAttr("name"));
                    // Now execute each child tag
                    mod.printOut(2,TAG + " Chapter name : " +ch.getName());
                    for (XMLNode code : chTag) {
                        exec(mod, ch, code);
                    }
                } else {
                    mod.printErr(4, "A non-chapter tag is found in <generate>, ignoreing it: " + tag);
                }
            }
        }

    }</span>

Log数据处理类ExtLogData.java : 

<span style="color:#333333">public class ExtLogData {

    public final static String TAG = "[ExtLogData]";

    private Chapter mCh;
    private LogLines mParsedLog = new LogLines();
    private BugReportModule mMod;

    public ExtLogData(BugReportModule mod, Section section, String chapterName, String infoId) {
        mMod = mod;

        // initParsedLog
        if (section != null) {
            // Load and parse the lines
            int cnt = section.getLineCount();
            for (int i = 0; i < cnt; i++) {
                LogLine log = new LogLine(mMod, section.getLine(i), LogLine.FMT_UNKNOWN, null);
                mParsedLog.add(log);
            }
            mMod.printOut(2, TAG + section.getShortName() + "[" + cnt + "]");
        }

        if (section != null && chapterName != null && mParsedLog.size() != 0) {
            mCh = mod.findOrCreateChapter(chapterName);
        }

        if (section != null && infoId != null) mMod.addInfo(infoId, mParsedLog);
    }

    public void generate() {
        if (mCh == null) {
            return;
        }

        new LogToolbar(mCh);
        DocNode log = new Block(mCh).addStyle("log");

        int cnt = mParsedLog.size();
        for (int i = 0; i < cnt; i++) {
            LogLine lg = mParsedLog.get(i);
            log.add(lg);
        }
    }

}
</span>

 

Load 扩展使用

<span style="color:#333333"><plugin name="ExamplePlugin">
	<load>
		<filter section="DUMP OF SERVICE dropbox" chapterName="DUMP/DUMP OF SERVICE dropbox" infoId="dumpdropboxlog" />
	</load>
</plugin></span>

 

HTML 报告截图:

 扩展 generate功能

code 实现

在 com.sonyericsson.chkbugreport.plugins.extxml.log.java 内部类 LogState 中:

两种方式获取需要筛选的Log:

  • 使用 BugReportModule.java 获取 Log 的 key(infoId)
  • 使用 Section 对象的 mShortName,在 Section 中获取 Log
    <span style="color:#333333">    public LogLines getParsedLog(BugReportModule mod) {
            LogLines parsedLog = new LogLines();
                int cnt = getLineCount();
                for (int i = 0; i < cnt; i++) {
                    LogLine log = new LogLine(mod, getLine(i), LogLine.FMT_UNKNOWN, null);
                    parsedLog.add(log);
                }
            return parsedLog;
        }</span>

 

generate 扩展使用

<span style="color:#333333"><plugin name="ExamplePlugin">
	<load>
		<filter section="DUMP OF SERVICE dropbox" chapterName="DUMP/DUMP OF SERVICE dropbox" infoId="dumpdropboxlog" />
	</load>
	<generate>
        <chapter name="WT Special characters/DUMP OF SERVICE dropbox">
			<text> DUMP OF SERVICE dropbox </text>
			<log>
				<filter log="dumpdropboxlog" matchLine="Kernel panic"/>
				<filter log="DUMP OF SERVICE dropbox" matchLine="SYSTEM_LAST_KMSG"/>
			</log>
        </chapter>
    </generate>
</plugin>
</span>

在 generate/chapter/log 标签中log参数可以是从 BugReportModule.java 中获取 Log 的 key(infoId),也可以是 Section 对象的 mShortName。

 

注意:推荐使用 matchLine 过滤,这个是原始Log的匹配,其他 matchTag、matchMsg、matchProc 针对上层,做过处理

 

HTML 报告截图:

 

 增添 hook功能

code 实现

对比 ChkBugReport工具 for Android 3 中 KernelLogPlugin 的hook扩展实现 ExtXMLPlugin 的扩展,并添加代码:

<span style="color:#333333">    private Hooks mHooks = new Hooks(this);

    @Override
    public void reset() {
        mLogs.clear();
        mHooks.reset();
    }

    @Override
    public void onHook(Module mod, XMLNode hook) {
        mHooks.add(hook);
    }

    @Override
    public void hook(Module mod) {
        // Execute the "hook" tag
        for (XMLNode hook : mXml) {
            if (!"hook".equals(hook.getName())) continue;
            String into = hook.getAttr("into");
            if (into == null) {
                mod.printErr(4, TAG + "Missing 'into' attribute in hook tag, ignoring whole tag!");
                this.onHook(mod, hook);
                continue;
            }
            Plugin dst = mod.getPlugin(into);
            if (dst == null) {
                mod.printErr(4, TAG + "Cannot find plugin to hook into: " + into);
                continue;
            }
            dst.onHook(mod, hook);
        }
    }

    @Override
    public void load(Module mod) {
        // Execute the "load" tag
        XMLNode load = mXml.getChild("load");
        if (load == null) {
            // <load> tag is missing, do nothing.
            return;
        }

        BugReportModule br = (BugReportModule) mod;
        for (XMLNode chTag : load) {
            String tag = chTag.getName();
            if ("filter".equals(tag)) {
                String section = chTag.getAttr("section");
                String chapterName = chTag.getAttr("chapterName");
                String infoId = chTag.getAttr("infoId");
                br.printOut(2, TAG + " section [" + section + "] , chapterName [" + chapterName + "] , infoId [" + infoId + "]");
                if(section == null) continue;
                loadLog(br, section, chapterName, infoId);
            }
        }
        // Execute the hooks
        mHooks.execute(br);
    }</span>


hook 扩展使用

<span style="color:#333333"><plugin name="ExamplePlugin">
	<hook>
		<filter matchLine="Kernel panic">
			<note text="Kernel panic" error="true"/>
		</filter>
		<filter matchLine="Kernel panic">
			<bug title="Kernel panic" text="!!!底层重启了!!!系统重启了!!!" prio="100" type="phone err" />
		</filter>
		<filter matchLine="SYSTEM_LAST_KMSG">
			<hide />
		</filter>
	</hook>
	<load>
		<filter section="DUMP OF SERVICE dropbox" chapterName="DUMP/DUMP OF SERVICE dropbox" infoId="dumpdropboxlog" />
	</load>
	<generate>
        <chapter name="WT Special characters/DUMP OF SERVICE dropbox">
			<text> DUMP OF SERVICE dropbox </text>
			<log>
				<filter log="dumpdropboxlog" matchLine="Kernel panic"/>
				<filter log="dumpdropboxlog" matchLine="SYSTEM_LAST_KMSG"/>
			</log>
        </chapter>
    </generate>
</plugin></span>

 

HTML 报告截图:

 hook功能缺陷:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xhBruce

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值