csdn 如何分析android的log (csdn如何赚取收益)

本文目录导航:

如何分析android的log csdn

首先,让我们看一看AndroidLog的格式。

下面这段log是以所谓的long格式打印出来的。

从前面Logcat的介绍中可以知道,long格式会把时间,标签等作为单独的一行显示。

[ 12-09 21:39:35.510 396: 416 I/ActivityManager ]Start :umengService_v1 for /:pid= uid= gids={, 3003, 1015,1028}[ 12-09 21:39:35.518 I/dalvikvm ]Turning on JNI app bug workarounds fortarget SDK version 8...[ 12-09 21:39:35.611 D/AgooService ]onCreate()我们以第一行为例:12-09 是日期,21:39:35.510是时间396是进程号,416是线程号;I代表log优先级,ActivityManager是log标签。

在应用开发中,这些信息的作用可能不是很大。

但是在系统开发中,这些都是很重要的辅助信息。

开发工程师分析的log很多都是由测试工程师抓取的,所以可能有些log根本就不是当时出错的log。

如果出现这种情况,无论你怎么分析都不太可能得出正确的结论。

如何能最大限度的避免这种情况呢?笔者就要求测试工程师报bug时必须填上bug发生的时间。

这样结合log里的时间戳信息就能大致判断是否是发生错误时的log。

而且根据测试工程师提供的bug发生时间点,开发工程师可以在长长的log信息中快速的定位错误的位置,缩小分析的范围。

同时我们也要注意,时间信息在log分析中可能被错误的使用。

例如:在分析多线程相关的问题时,我们有时需要根据两段不同线程中log语句执行的先后顺序来判断错误发生的原因,但是我们不能以两段log在log文件中出现的先后做为判断的条件,这是因为在小段时间内两个线程输出log的先后是随机的,log打印的先后顺序并不完全等同于执行的顺序。

那么我们是否能以log的时间戳来判断呢?同样是不可以,因为这个时间戳实际上是系统打印输出log时的时间,并不是调用log函数时的时间。

遇到这种情况唯一的办法是在输出log前,调用系统时间函数获取当时时间,然后再通过log信息打印输出。

这样虽然麻烦一点,但是只有这样取得的时间才是可靠的,才能做为我们判断的依据。

另外一种误用log中时间戳的情况是用它来分析程序的性能。

一个有多年工作经验的工程师拿着他的性能分析结果给笔者看,但是笔者对这份和实际情况相差很远的报告表示怀疑,于是询问这位工程师是如何得出结论的。

他的回答让笔者很惊讶,他计算所采用的数据就是log信息前面的时间戳。

前面我们已经讲过,log前面时间戳和调用log函数的时间并不相同,这是由于系统缓冲log信息引起的,而且这两个时间的时间差并不固定。

所以用log信息前附带的时间戳来计算两段log间代码的性能会有比较大的误差。

正确的方法还是上面提到的:在程序中获取系统时间然后打印输出,利用我们打印的时间来计算所花费的时间。

了解了时间,我们再谈谈进程Id和线程Id,它们也是分析log时很重要的依据。

我们看到的log文件,不同进程的log信息实际上是混杂在一起输出的,这给我们分析log带来了很大的麻烦。

有时即使是一个函数内的两条相邻的log,也会出现不同进程的log交替输出的情况,也就是A进程的第一条log后面跟着的是B进程的第二条log,对于这样的组合如果不细心分析,就很容易得出错误的结论。

这时一定要仔细看log前面的进程Id,把相同Id的log放到一起看。

不同进程的log有这样的问题,不同的线程输出的log当然也存在着相同的问题。

Logcat加上-vthread就能打印出线程Id。

但是有一点也要引起注意,就是Android的线程Id和我们平时所讲的Linux线程Id并不完全等同。

首先,在Android系统中,C++层使用的Linux获取线程Id的函数gettid()是不能得到线程Id的,调用gettid()实际上返回的是进程Id。

作为替代,我们可以调用pthread_self()得到一个唯一的值来标示当前的native线程。

Android也提供了一个函数androidGetThreaId()来获取线程Id,这个函数实际上就是在调用pthread_self函数。

但是在Java层线程Id又是另外一个值,Java层的线程Id是通过调用Thread的getId方法得到的,这个方法的返回值实际上来自Android在每个进程的java层中维护的一个全局变量,所以这个值和C++层所获得的值并不相同。

这也是我们分析log时要注意的问题,如果是Java层线程Id,一般值会比较小,几百左右;如果是C++层的线程,值会比较大。

在前里面的log样本中,就能很容易的看出,第一条log是Jave层输出的log,第二条是native层输出的。

明白了这些,我们在分析log时就不要看见两段log前面的线程Id不相同就得出是两个不同线程log的简单结论,还要注意Jave层和native层的区别,这样才能防止被误导。

AndroidLog的优先级在打印输出时会被转换成V,I,D,W,E等简单的字符标记。

在做系统log分析时,我们很难把一个log文件从头看到尾,都是利用搜索工具来查找出错的标记。

比如搜索“E/”来看看有没有指示错误的log。

所以如果参与系统开发的每个工程师都能遵守Android定义的优先级含义来输出log,这会让我们繁重的log分析工作变得相对轻松些。

Android比较常见的严重问题有两大类,一是程序发生崩溃;二是产生了ANR。

程序崩溃和ANR既可能发生在java层,也可能发生在native层。

如果问题发生在java层,出错的原因一般比较容易定位。

如果是native层的问题,在很多情况下,解决问题就不是那么的容易了。

我们先看一个java层的崩溃例子:I/ActivityManager( 396): Start for activity /:pid=1760 uid= gids={, 1028}D/AndroidRuntime( 1760): Shutting downVMW/dalvikvm( 1760): threadid=1: threadexiting with uncaught exception(group=0x40c)E/AndroidRuntime( 1760): FATALEXCEPTION: mainE/AndroidRuntime( 1760): Unable to start activityComponentInfo{/}/AndroidRuntime( 1760): (:2180)E/AndroidRuntime( 1760): (:2230)E/AndroidRuntime( 1760): $600(:141)E/AndroidRuntime( 1760): $(:1234)E/AndroidRuntime( 1760): (:99)E/AndroidRuntime( 1760): (:137)E/AndroidRuntime( 1760): (:5050)E/AndroidRuntime( 1760): (NativeMethod)E/AndroidRuntime( 1760): (:511)E/AndroidRuntime( 1760): $(:793)E/AndroidRuntime( 1760): (:560)E/AndroidRuntime( 1760): (NativeMethod)E/AndroidRuntime( 1760): Caused /AndroidRuntime( 1760): (:29)E/AndroidRuntime( 1760): (:17)E/AndroidRuntime( 1760): (:5104)E/AndroidRuntime( 1760): (:1080)E/AndroidRuntime( 1760): (:2144)E/AndroidRuntime( 1760): ... 11moreI/Process ( 1760): Sending : 1760 SIG: 9W/ActivityManager( 396): Force finishing /层的代码发生crash问题时,系统往往会打印出很详细的出错信息。

比如上面这个例子,不但给出了出错的原因,还有出错的文件和行数。

根据这些信息,我们会很容易的定位问题所在。

native层的crash虽然也有栈log信息输出,但是就不那么容易看懂了。

下面我们再看一个native层crash的例子:F/libc ( 2102): Fatal signal 11 (SIGSEGV) at 0x (code=1), thread2102 (testapp)D/dalvikvm():GC_FOR_ALLOC freed 604K, 11% free K/K, paused 36ms, total36msI/dalvikvm-heap():Grow heap (frag case) to 11.831MB for -byteallocationD/dalvikvm():GC_FOR_ALLOC freed 1K, 11% free K/K, paused 34ms, total34msI/DEBUG ( 127):*** *** *** *** *** *** *** *** *** *** *** *** *** *** ******I/DEBUG ( 127):Build fingerprint:Android/full_maguro/maguro:4.2.2/JDQ39/..:userdebug/test-keysI/DEBUG ( 127):Revision: 9I/DEBUG ( 127):pid: 2102, tid: 2102, name: testapp >>>./testapp <<<I/DEBUG ( 127):signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addrI/DEBUG ( 127): r0 r r2 400ff520 rI/DEBUG ( 127): r4 400ff469 r5beb4ab24 r6 r7beb4ab2cI/DEBUG ( 127): r8 r sl fpbeb4ab1cI/DEBUG ( 127): ip 4009b5dc spbeb4aae8 lr 400ff46f pc400ff45e cpsr I/DEBUG ( 127): d0 8dae8 d1 4108cedcec8I/DEBUG ( 127): d2 4108cefcee8 d3 4108cfcf08I/DEBUG ( 127): d4 4108c5ac598 d5 4108cac5b8I/DEBUG ( 127): d6 4108cece58 d7 4108cece78I/DEBUG ( 127): d8 d9 I/DEBUG ( 127): d10 dI/DEBUG ( 127): d dI/DEBUG ( 127): d14 dI/DEBUG ( 127): d16 c1dcf7c087fec8b4 d173fdd2f1a9fcI/DEBUG ( 127): d18 41c7b1ac dI/DEBUG ( 127): d20 dI/DEBUG ( 127): d22 dI/DEBUG ( 127): d24 dI/DEBUG ( 127): d26 dI/DEBUG ( 127): d28 dI/DEBUG ( 127): d30 dI/DEBUG ( 127): scr I/DEBUG ( 127):I/DEBUG ( 127):backtrace:I/DEBUG ( 127): #00 pce /system/bin/testappI/DEBUG ( 127): #01 pcb /system/bin/testappI/DEBUG ( 127): #02 pcf /system/lib/ (__libc_init+38)I/DEBUG ( 127): #03 pc /system/bin/testappI/DEBUG ( 127):I/DEBUG ( 127):stack:I/DEBUG ( 127): beb4aaa8 c8I/DEBUG ( 127): beb4aaac I/DEBUG ( 127): beb4aab0 I/DEBUG ( 127): beb4aab4 401cbee0 /system/bin/linkerI/DEBUG ( 127): beb4aab8 I/DEBUG ( 127): beb4aabc d /system/lib/ (__libc_fini)I/DEBUG ( 127): beb4aac0 d /system/lib/ (__libc_fini)I/DEBUG ( 127): beb4aac4 eac /system/bin/testappI/DEBUG ( 127): beb4aac8 I/DEBUG ( 127): beb4aacc 400ff469 /system/bin/testappI/DEBUG ( 127): beb4aad0 beb4ab24 [stack]I/DEBUG ( 127): beb4aad4 I/DEBUG ( 127): beb4aad8 beb4ab2c [stack]I/DEBUG ( 127): beb4aadc I/DEBUG ( 127): beb4aae0 df0027adI/DEBUG ( 127): beb4aae4 I/DEBUG ( 127): #00 beb4aae8 I/DEBUG ( 127): ........ ........I/DEBUG ( 127): #01 beb4aae8 I/DEBUG ( 127): beb4aaec 401e9721 /system/lib/ (__libc_init+40)I/DEBUG ( 127): #02 beb4aaf0 beb4ab08 [stack]I/DEBUG ( 127): beb4aaf4 I/DEBUG ( 127): beb4aaf8 I/DEBUG ( 127): beb4aafc I/DEBUG ( 127): beb4ab00 I/DEBUG ( 127): beb4ab04 400ff404 /system/bin/testappI/DEBUG ( 127):这个log就不那么容易懂了,但是还是能从中看出很多信息,让我们一起来学习如何分析这种log。

首先看下面这行:pid: 2102, tid: 2102,name: testapp >>>./testapp <<<从这一行我们可以知道crash进程的pid和tid,前文我们已经提到过,Android调用gettid函数得到的实际是进程Id号,所以这里的pid和tid相同。

知道进程号后我们可以往前翻翻log,看看该进程最后一次打印的log是什么,这样能缩小一点范围。

接下来内容是进程名和启动参数。

再接下来的一行比较重要了,它告诉了我们从系统角度看,出错的原因:signal 11 (SIGSEGV), code 1(SEGV_MAPERR), fault addr signal11是Linux定义的信号之一,含义是Invalidmemory reference,无效的内存引用。

加上后面的“faultaddr ”我们基本可以判定这是一个空指针导致的crash。

当然这是笔者为了讲解而特地制造的一个Crash的例子,比较容易判断,大部分实际的例子可能就没有那么容易了。

再接下来的log打印出了cpu的所有寄存器的信息和堆栈的信息,这里面最重要的是从堆栈中得到的backtrace信息:I/DEBUG ( 127):backtrace:I/DEBUG ( 127): #00 pce /system/bin/testappI/DEBUG ( 127): #01 pcb /system/bin/testappI/DEBUG ( 127): #02 pcf /system/lib/ (__libc_init+38)I/DEBUG ( 127): #03 pc /system/bin/testapp因为实际的运行系统里没有符号信息,所以打印出的log里看不出文件名和行数。

这就需要我们借助编译时留下的符号信息表来翻译了。

Android提供了一个工具可以来做这种翻译工作:arm-eabi-addr2line,位于prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin目录下。

用法很简单:#./arm-eabi-addr2line -f -eout/target/product/hammerhead/symbols/system/bin/testapp0xe参数-f表示打印函数名;参数-e表示带符号表的模块路径;最后是要转换的地址。

这条命令在笔者的编译环境中得到的结果是:memcpy /home/rd/compile/android-4.4_r1.2/bionic/libc/include/string.h:108剩余三个地址翻译如下:main /home/rd/compile/android-4.4_r1.2/packages/apps/testapp/app_:38out_vformat /home/rd/compile/android-4.4_r1.2/bionic/libc/bionic/libc_:361_start libgcc2.c:0利用这些信息我们很快就能定位问题了。

不过这样手动一条一条的翻译比较麻烦,笔者使用的是从网上找到的一个脚本,可以一次翻译所有的行,有需要的读者可以在网上找一找。

csdn 如何分析android的log (csdn如何赚取收益)

cstdio头文件为什么会编译错误?

在使用`cstdio`头文件时,可能会出现编译错误的情况。

以下是一些常见的可能导致编译错误的原因:1. 头文件未被正确包含在使用`cstdio`头文件时,应该使用 `#include <cstdio>` 或者 `#include <stdio.h>` 来正确包含头文件。

如果没有包含此头文件或者包含的方式不正确,就会出现编译错误。

2. 编译器不支持 C99 标准C99 标准引入了一些新的特性,例如定义变长数组和指定函数参数的名称等功能,这些功能需要编译器支持才能正确编译。

如果编译器不支持 C99 标准,那么在包含`cstdio`头文件时可能会出现编译错误。

3. 使用了过时的函数`cstdio`头文件中定义了许多常用的输入输出函数,如`printf`、`scanf`、`fopen`等。

然而,某些旧版本的编译器可能已经将一些函数标记为过时(deprecated)或不推荐使用,而且在某些操作系统上,使用某些函数可能需要显式地声明它们。

这种情况下,在包含`cstdio`头文件时可能会出现编译错误。

4. 名称空间冲突某些编译器和开发环境可能具有自己的标准库实现,其中定义了与`cstdio`头文件中的函数名称相同的函数。

这种情况下,在包含`cstdio`头文件时可能会出现名称空间冲突,导致编译错误。

综上所述,如果在使用`cstdio`头文件时遇到了编译错误,可以检查是否正确地包含了头文件,使用了正确的编译选项和版本的编译器,并避免使用过时的函数或名称空间冲突。

此外,也可以考虑使用其他替代的头文件和函数来代替`cstdio`头文件中的功能。

2020年浙江省高校计算机二级C语言考试大纲

要参加2020年浙江省高校计算机等级考试的小伙伴们注意了,环球青藤小编整理分享了2020年浙江省高校计算机二级C语言考试大纲,小伙伴们快来看看吧,希望以下内容对大家接下来的考试有所帮助,更多计算机等级考试信息敬请关注环球青藤计算机二级频道。

2020年浙江省高校计算机二级C语言考试大纲考试目标C程序设计是高校重要的计算机基础课程,它以结构化程序设计语言——C语言为平台,介绍程序设计的思想和方法。

学生通过C语言的学习和编程训练,掌握高级程序设计语言的知识,理解计算思维的思想与方法,掌握基本的程序设计过程和技巧,具备基本的问题分析、数据表达以及算法描述和编程实现的能力。

主要考核学生利用计算机求解常见基本问题的能力。

基本要求1、熟练掌握C程序语言的基本知识。

2、具备程序设计基本能力,能熟练地阅读、分析和编写C程序。

3、掌握一种C语言的编译和编程环境,能熟练地调试程序。

4、掌握结构化程序设计的方法,具有良好的程序设计风格。

5、掌握程序设计的常用算法。

考试内容一、数据的定义1、基本类型(整型,实型,字符型)(1)常量各种表示形式的整数、实数和字符(串)常量,符号常量的定义和使用,包括整数的十进制、八进制和十六进制的表示形式、长整型常量的表示形式,实数的浮点表示法和科学记数法,字符的转义序列,常用符号常量的含义(如NULL、EOF等)。

(2)变量变量的定义和初始化。

2、构造类型(1)数组一维和二维数组的定义和初始化,数组元素的引用,包括一维字符数组和字符串,二维字符数组和字符串数组。

(2)结构结构类型的定义,结构变量的定义和初始化,结构变量成员的引用。

3、指针(1)指针和地址的概念;(2)指针变量的定义和初始化;(3)通过指针引用指向实体。

4、构造类型和指针类型的混合定义及应用(1)指针、数组和地址间的关系;(2)指针数组;(3)结构数组;(4)结构指针;(5)结构中含指针或数组;(6)指向指针的指针(即二级指针)。

5、空类型的定义和使用6、变量的存储类别、作用域和生存期(1)变量的存储类别,包括auto自动型、static静态型、extern外部参照型;(2)全局变量和局部变量,包括自动局部变量和静态局部变量、全局变量和静态全局变量、外部变量。

二、运算及流程控制1、基本运算运算符的功能,运算符的优先级、结合性和目数,自动类型转换和强制类型转换。

2、表达式各类表达式的组成规则和计算过程。

3、语句(1)表达式语句、空语句和复合语句;(2)简单控制语句(break、continue、return);(3)选择控制语句(if、switch);(4)重复控制语句(for、while、do—while)。

三、程序结构和函数1、程序结构main函数与其他函数之间的关系,包括标准库函数和自定义函数。

2、函数的定义(1)函数定义的一般形式;(2)函数的参数(形式参数和实在参数)及参数传递,包括指针作为函数的参数;(3)函数的返回值,包括指针作为函数的返回值。

3、函数的调用(1)函数调用的一般形式;(2)函数的嵌套调用和递归调用;(3)标准库函数的调用。

常用数学函数:cos、sqrt、pow、exp、fabs、log、log10等;常用字符函数:isalnum、isalpha、isdigit、islower、toupper等;常用字符串函数:strcpy、strcmp、strcat、strlen等。

四、数据的输入和输出1、文件的基本概念2、标准文件的输入和输出,常用输入输出函数:scanf、printf、getchar、putchar、gets、puts等。

3、缓冲文件系统(文本文件)(1)文件的打开和关闭,常用函数:fopen和fclose;(2)文件的基本读写操作,常用函数:fscanf、fprintf、fgetc、fputc、fgets、fputs等;(3)文件的状态检测,常用函数feof等。

五、编译预处理1、编译预处理的基本概念2、宏定义3、文件包含六、常用算法1、检索(查找)算法:无序数据序列之顺序查找法和有序数据序列之二分查找法2、分类(排序)算法:冒泡法和选择法3.遍历算法:一维数组和二维数组的遍历4、数值计算、数据的查询统计和修改、字符处理等常用算法以上就是小编整理的2020年浙江省高校计算机二级C语言考试大纲,准备参加二级考试的同学们都来了解一下吧。

想要及时了解考试动态的小伙伴可“免费预约短信提醒”届时环球青藤会及时为大家推送全国计算机等级考试相关信息提醒。

环球青藤友情提示:对于想要参加计算机二级考试的小伙伴们,环球青藤特地为您准备了计算机二级考试资料,如有需要请点击文章下方“免费下载>>>计算机二级考试资料”下载学习。

你可能想看:
« 上一篇
下一篇 »

相关推荐

FreeBasic:强大免费开源的64位basic编译器及应用优势

2025年05月10日

82阅读

脊柱侧弯矫正方法大盘点:运动康复、支具矫正等多种方式

2025年05月09日

87阅读

如何在winForm标题栏去掉标题文字且任务栏图标正常显示

2025年05月09日

86阅读

十一黄金周促销广告词大全,国庆购物狂欢等你来

2025年05月09日

78阅读

关闭快速编辑模式及插入模式,设置控制台指定文字颜色举例

2025年05月09日

63阅读

黄金搭档低糖高钙饮品包装及成分功效全解析,适合人群要知晓

2025年05月09日

91阅读