仓酷云

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 1821|回复: 19
打印 上一主题 下一主题

[学习教程] IOS编程之Android代码调试工具traceview和dmtracedump的妨害归纳仓酷云

[复制链接]
海妖 该用户已被删除
跳转到指定楼层
楼主
发表于 2015-1-18 11:49:33 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
继承自相应的不可变类比如NSMutableArray继承自NSArray他们都添加了可以改变对象内容的方法比如-(void)addObject:(id)anObject添加对象-(void)removeObject:(id)anObject删除对象上面只是一个大概的总结Android程序调试工具

Google为我们供应的代码调试工具的亮点:traceviewdmtracedump。有了这两个工具,我们调试程序剖析bug就十分轻车熟路了。traceview匡助我们剖析程序功能,dmtracedump天生函数挪用图。遗憾的是,google供应的dmtracedump是个失利的工具,其实不能画图,本文会具体先容办理计划,完成画图。
天生.trace文件

android.os.Debug类,个中主要的两个办法Debug.startMethodTracing()和Debug.stopMethodTracing()。这两个办法用来创立.trace文件,将从Debug.startMethodTracing()入手下手,到Debug.stopMethodTracing()停止,时代一切的挪用历程保留在.trace文件中,包含挪用的函数称号和实行的工夫等信息。
把上面代码分离在加在调试肇端代码的地位,和停止地位。


  • Debug.startMethodTracing(“test”);
  • Debug.stopMethodTracing();
Debug.startMethodTracing(“test”);Debug.stopMethodTracing();

个中参数test是要创立的trace文件的称号,test.trace。默许路径是/sdcard/test.trace,也能够本人制订/data/log/test,暗示文件在/data/log/test.trace。



traceview

在SDK中实行:
./traceviewtest.trace

我们能够失掉
1.程序中每一个线程挪用办法的启动和中断工夫

<br>

2.函数实行的信息和效力剖析

<br>



dmtracedump

dmtracedump底本的意图是将全部挪用历程和工夫剖析分离,以函数挪用图的情势体现出来。但是google这个项目一向处于broken形态,迟迟不克不及失掉完美。如今的dmtracdump只要-o选项可使用,在终端上列出函数挪用信息,和traceview功效类似,假如实行./dmtracedump&ndash;gtest.pngtest.trace就会卡住不动。后来我觉得是test.trace文件的成绩,对文件的停止符稍作修正,画出了一副雷人的图片:

<br>
厥后,搜到了收集上有牛人供应了dmtracedump的替换(这是原文链接),是一个python剧本,借助dot来绘制矢量图。python剧本必定要注重对齐格局,对齐缩进就是他的逻辑布局。

  • #!/usr/bin/envpython
  • """
  • turnthetraceviewdataintoajpgpic,showingmethodscallrelationship
  • """
  • importsys
  • importos
  • importstruct
  • importre
  • ################################################################################
  • ########################GlobalVariable#####################################
  • ################################################################################
  • target_thread=1#thethreadthatwewanttotrack,filtoutotherthreads
  • #all_actions=["enter","exit","exception","reserved"]
  • all_threads={}
  • all_methods={}
  • all_records=[]
  • parent_methods={}
  • child_methods={}
  • method_calls={}
  • ################################################################################
  • ##############################Methods#####################################
  • ################################################################################
  • defadd_one_thread(line):
  • fields=line.split("/t")
  • all_threads[int(fields[0],10)]=fields
  • defadd_one_method(line):
  • fields=line.split("/t")
  • all_methods[int(fields[0],16)]=fields
  • defadd_one_record(one):
  • thread_id,=struct.unpack("B",one[:1])
  • if(thread_id==target_thread):
  • tmp,=struct.unpack("L",one[1:5])
  • method_id=(tmp/4)*4;
  • method_action=tmp%4;
  • time_offset,=struct.unpack("L",one[5:])
  • all_records.append([thread_id,method_id,method_action,time_offset])
  • defhandle_one_call(parent_method_id,method_id):
  • ifnot(parent_methods.has_key(parent_method_id)):
  • parent_methods[parent_method_id]=1
  • ifnot(child_methods.has_key(method_id)):
  • child_methods[method_id]=1
  • ifmethod_calls.has_key(parent_method_id):
  • ifmethod_calls[parent_method_id].has_key(method_id):
  • method_calls[parent_method_id][method_id]+=1
  • else:
  • method_calls[parent_method_id][method_id]=1
  • else:
  • method_calls[parent_method_id]={}
  • method_calls[parent_method_id][method_id]=1
  • defgen_funcname(method_id):
  • r1=re.compile(r[/{1}lt;>])
  • str1=r1.sub("_",all_methods[method_id][1])
  • str2=r1.sub("_",all_methods[method_id][2])
  • returnstr1+"_"+str2
  • defgen_dot_script_file():
  • myoutfile=open("graph.dot","w")
  • myoutfile.write("digraphvanzo{/n/n");
  • foroneinall_methods.keys():
  • ifparent_methods.has_key(one):
  • myoutfile.write(gen_funcname(one)+"[shape=rectangle];/n")
  • else:
  • ifchild_methods.has_key(one):
  • myoutfile.write(gen_funcname(one)+"[shape=ellipse];/n")
  • foroneinmethod_calls.keys():
  • fortwoinmethod_calls[one]:
  • myoutfile.write(gen_funcname(one)+->+gen_funcname(two)+[label="+str(method_calls[one][two])+"fontsize="10"];/n)
  • myoutfile.write("/n}/n");
  • myoutfile.close

  • ################################################################################
  • ##########################Scriptstartsfromhere#############################
  • ################################################################################
  • iflen(sys.argv)<2:
  • printNoinputfilespecified.
  • sys.exit()
  • ifnot(os.path.exists(sys.argv[1])):
  • print"inputfilenotexists"
  • sys.exit()
  • #Nowhandlethetextpart
  • current_section=0
  • forlineinopen(sys.argv[1]):
  • line2=line.strip()
  • if(line2.startswith("*")):
  • if(line2.startswith("*version")):
  • current_section=1
  • else:
  • if(line2.startswith("*threads")):
  • current_section=2
  • else:
  • if(line2.startswith("*methods")):
  • current_section=3
  • else:
  • if(line2.startswith("*end")):
  • current_section=4
  • break
  • continue
  • ifcurrent_section==2:
  • add_one_thread(line2)
  • ifcurrent_section==3:
  • add_one_method(line2)

  • #Nowhandlethebinarypart
  • mybinfile=open(sys.argv[1],"rb")
  • alldata=mybinfile.read()
  • mybinfile.close()
  • pos=alldata.find("SLOW")
  • offset,=struct.unpack("H",alldata[pos+6:pos+8])
  • pos2=pos+offset#pos2iswheretherecordbegin
  • numofrecords=len(alldata)-pos2
  • numofrecords=numofrecords/9
  • foriinxrange(numofrecords):
  • add_one_record(alldata[pos2+i*9:pos2+i*9+9])
  • my_stack=[0]
  • foronerecordinall_records:
  • thread_id=onerecord[0];
  • method_id=onerecord[1];
  • action=onerecord[2];
  • time=onerecord[3];
  • if(action==0):
  • if(len(my_stack)>1):
  • parent_method_id=my_stack[-1]
  • handle_one_call(parent_method_id,method_id)
  • my_stack.append(method_id)
  • else:
  • if(action==1):
  • if(len(my_stack)>1):
  • my_stack.pop()
  • gen_dot_script_file()
  • os.system("dot-Tjpggraph.dot-ooutput.jpg;rm-fgraph.dot");
#!/usr/bin/envpython"""turnthetraceviewdataintoajpgpic,showingmethodscallrelationship"""importsysimportosimportstructimportre########################################################################################################GlobalVariable#####################################################################################################################target_thread=1#thethreadthatwewanttotrack,filtoutotherthreads#all_actions=["enter","exit","exception","reserved"]all_threads={}all_methods={}all_records=[]parent_methods={}child_methods={}method_calls={}##############################################################################################################Methods#####################################################################################################################defadd_one_thread(line):fields=line.split("/t")all_threads[int(fields[0],10)]=fieldsdefadd_one_method(line):fields=line.split("/t")all_methods[int(fields[0],16)]=fieldsdefadd_one_record(one):thread_id,=struct.unpack("B",one[:1])if(thread_id==target_thread):tmp,=struct.unpack("L",one[1:5])method_id=(tmp/4)*4;method_action=tmp%4;time_offset,=struct.unpack("L",one[5:])all_records.append([thread_id,method_id,method_action,time_offset])defhandle_one_call(parent_method_id,method_id):ifnot(parent_methods.has_key(parent_method_id)):parent_methods[parent_method_id]=1ifnot(child_methods.has_key(method_id)):child_methods[method_id]=1ifmethod_calls.has_key(parent_method_id):ifmethod_calls[parent_method_id].has_key(method_id):method_calls[parent_method_id][method_id]+=1else:method_calls[parent_method_id][method_id]=1else:method_calls[parent_method_id]={}method_calls[parent_method_id][method_id]=1defgen_funcname(method_id):r1=re.compile(r[/{1}lt;>])str1=r1.sub("_",all_methods[method_id][1])str2=r1.sub("_",all_methods[method_id][2])returnstr1+"_"+str2defgen_dot_script_file():myoutfile=open("graph.dot","w")myoutfile.write("digraphvanzo{/n/n");foroneinall_methods.keys():ifparent_methods.has_key(one):myoutfile.write(gen_funcname(one)+"[shape=rectangle];/n")else:ifchild_methods.has_key(one):myoutfile.write(gen_funcname(one)+"[shape=ellipse];/n")foroneinmethod_calls.keys():fortwoinmethod_calls[one]:myoutfile.write(gen_funcname(one)+->+gen_funcname(two)+[label="+str(method_calls[one][two])+"fontsize="10"];/n)myoutfile.write("/n}/n");myoutfile.close##########################################################################################################Scriptstartsfromhere#############################################################################################################iflen(sys.argv)<2:printNoinputfilespecified.sys.exit()ifnot(os.path.exists(sys.argv[1])):print"inputfilenotexists"sys.exit()#Nowhandlethetextpartcurrent_section=0forlineinopen(sys.argv[1]):line2=line.strip()if(line2.startswith("*")):if(line2.startswith("*version")):current_section=1else:if(line2.startswith("*threads")):current_section=2else:if(line2.startswith("*methods")):current_section=3else:if(line2.startswith("*end")):current_section=4breakcontinueifcurrent_section==2:add_one_thread(line2)ifcurrent_section==3:add_one_method(line2)#Nowhandlethebinarypartmybinfile=open(sys.argv[1],"rb")alldata=mybinfile.read()mybinfile.close()pos=alldata.find("SLOW")offset,=struct.unpack("H",alldata[pos+6:pos+8])pos2=pos+offset#pos2iswheretherecordbeginnumofrecords=len(alldata)-pos2numofrecords=numofrecords/9foriinxrange(numofrecords):add_one_record(alldata[pos2+i*9:pos2+i*9+9])my_stack=[0]foronerecordinall_records:thread_id=onerecord[0];method_id=onerecord[1];action=onerecord[2];time=onerecord[3];if(action==0):if(len(my_stack)>1):parent_method_id=my_stack[-1]handle_one_call(parent_method_id,method_id)my_stack.append(method_id)else:if(action==1):if(len(my_stack)>1):my_stack.pop()gen_dot_script_file()os.system("dot-Tjpggraph.dot-ooutput.jpg;rm-fgraph.dot");

修正,/t变成        ,/n变成

在盘算器的源码onCreate中增加

  • Debug.startMethodTracing(“calc”);
  • Log.v(LOG_TAGS”+++++++++++++++++++++++++test++++++++++++++++”);
  • Debug.stopMethodTracing();
Debug.startMethodTracing(“calc”);Log.v(LOG_TAGS”+++++++++++++++++++++++++test++++++++++++++++”);Debug.stopMethodTracing();运转剧本失掉calc.trace,画出out.jpg

<br>
可当失掉的trace文件对照庞大时绘图就会溃散。修正剧本最初实行dot命令时的参数,jpg格局太年夜简单溃散,-Tjpg改成-Tpng:gd,画年夜幅png。
我拿camera做了个实行,失掉的png甚年夜,这是个中一角:

<br>

除了在程序加载的时候把我的view加载到他上目前我还没用到过其他的苹果一直很推崇MVC的程序结构视图模型控制器简单说就是视图负责显示内容模型负责所有数据的保存结构或者一些其他数据操作控制器是用来协调视图和模型举车的发动机系统的例子
精灵巫婆 该用户已被删除
沙发
发表于 2015-1-21 15:52:13 | 只看该作者
众多研发人员积极参与到iOS平台的开发中来也就不足为奇了。
再见西城 该用户已被删除
板凳
发表于 2015-1-25 13:59:58 | 只看该作者
看完这个你就可以有多种选择来踏入做应用的阶段
蒙在股里 该用户已被删除
地板
发表于 2015-1-26 20:10:52 | 只看该作者
才在自己的Windows电脑上安装配置成功了一个完美的Mac OS X Lion(10.7.4)系统,而且下载了Xcode4.5的最新版本。虽然不能实机调试,但是作为iOS开发学习已经非常完美了。
老尸 该用户已被删除
5#
发表于 2015-1-27 05:41:03 | 只看该作者
培训的时候很痛苦,每天要待12个小时,上午讲课,下午和晚自习解决作业,看文档,学习的时候感觉就是资料太少,而且看着资料也不明所以,非常痛苦,
再现理想 该用户已被删除
6#
发表于 2015-1-31 08:05:02 | 只看该作者
开始的时候甚至想放弃,不过想想自己的未来,只能咬牙坚持,课下就不停的缠着老师。放学就补基础,这些基础的东西没有速成的,只有刻苦努力。我是后来发现的,转变自己的心态,不要读书看资料当成一种痛苦
只想知道 该用户已被删除
7#
发表于 2015-2-1 17:27:39 | 只看该作者
因为我们老师也是自学的,给我们讲课说的最多的就是百度,谷歌,查文档。
深爱那片海 该用户已被删除
8#
发表于 2015-2-6 02:04:00 | 只看该作者
培训时可以选择安卓,iOS,Java,因为实习的时候我选了安卓,当时实习时间只有三周,学的晕头转向,而java我也没学过,iOS的基础是C语言,这个大学里还是学过的,于是选择了iOS。
因胸联盟 该用户已被删除
9#
发表于 2015-2-14 22:03:26 | 只看该作者
在百度搜索你想要了解的类名(苹果的cocoa和cocoatouch框架的类名很有特点很容易搜到,前缀都是NS or UI),看别人写的博客详解
愤怒的大鸟 该用户已被删除
10#
发表于 2015-2-24 11:23:43 | 只看该作者
培训时可以选择安卓,iOS,Java,因为实习的时候我选了安卓,当时实习时间只有三周,学的晕头转向,而java我也没学过,iOS的基础是C语言,这个大学里还是学过的,于是选择了iOS。
简单生活 该用户已被删除
11#
发表于 2015-3-2 12:20:25 | 只看该作者
在百度搜索你想要了解的类名(苹果的cocoa和cocoatouch框架的类名很有特点很容易搜到,前缀都是NS or UI),看别人写的博客详解
小女巫 该用户已被删除
12#
发表于 2015-3-6 16:34:36 | 只看该作者
其实在培训的过程中,学习到最多的就是查资料的方式,当时感觉老师好坑,什么都不告诉我们,让我们自己去查,但是现在觉得还是要自己解决问题,这样才能理解的更加深入。
活着的死人 该用户已被删除
13#
发表于 2015-3-13 04:09:44 | 只看该作者
down下code4app网站的每个分类的代码挨着看
金色的骷髅 该用户已被删除
14#
发表于 2015-3-19 14:05:29 | 只看该作者
培训时可以选择安卓,iOS,Java,因为实习的时候我选了安卓,当时实习时间只有三周,学的晕头转向,而java我也没学过,iOS的基础是C语言,这个大学里还是学过的,于是选择了iOS。
飘灵儿 该用户已被删除
15#
发表于 2015-3-23 18:03:48 | 只看该作者
重要的是,放眼全球也的确找不到第二个如苹果iOS平台这样健壮、完整、先进而且为开发者带来真实收益的开发平台来。
透明 该用户已被删除
16#
发表于 2015-3-24 08:26:27 | 只看该作者
其实在培训的过程中,学习到最多的就是查资料的方式,当时感觉老师好坑,什么都不告诉我们,让我们自己去查,但是现在觉得还是要自己解决问题,这样才能理解的更加深入。
不帅 该用户已被删除
17#
发表于 2015-4-10 10:45:16 | 只看该作者
学习ios没什么捷径,关键在于多动手敲,曾看到前辈开玩笑说怎么快速学会某技术,答案是:“提高打字速度,快点写代码就能快点学会了”。
admin 该用户已被删除
18#
发表于 2015-4-13 03:01:08 | 只看该作者
每个行业都一样,想要一天学有所成是不可能的,一定要做好努力的准备,做ios不是简单的学会oc语言。不怕多走弯路,就怕不肯动手。
分手快乐 该用户已被删除
19#
发表于 2015-4-16 01:10:20 | 只看该作者
有办法利用自己手头的电脑立刻开始这个美妙旅程的。
海妖 该用户已被删除
20#
 楼主| 发表于 2015-5-4 22:09:21 | 只看该作者
要学会通过各种方法将面前的事情变成自己感兴趣的,那专研起来就不会是无聊和折磨了。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|仓酷云 鄂ICP备14007578号-2

GMT+8, 2024-5-2 07:38

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表