xcode 能不能docker attachh其它进程

> 苹果软件编程工具(Xcode MAC)V7.1 官方版
苹果软件编程工具(Xcode MAC)V7.1 官方版xcode mac 下载
Xcode mac是一款由苹果公司针对苹果系统开发的编程软件,苹果软件编程工具(Xcode MAC)是Mac OS系统以及IOS系统开发者专用于构建Mac OS X 及 iOS 应用程序的完整工具集,Xcode具有统一的用户界面设计,编码,测试,调试都在一个简单的窗口内完成。最新 xcode mac 版本苹果软件编程工具(Xcode MAC)官方介绍:Xcode前身是继承自NeXT的Project Builder。The Xcode suite 包含有GNU Compiler Collection自由软件 (GCC、 apple-darwin9-gcc-4.0.1 以及 apple-darwin9-gcc-4.2.1, 默认的是第一个),并支持 C语言、C++、Fortran、Objective-C、Objective-C++、Java、AppleScript、Python以及Ruby,还提供Cocoa、Carbon以及Java等编程模式。协力厂商更提供了 GNU Pascal,Free Pascal, Ada, C#, Perl, Haskell 和 D语言。Xcode套件使用 GDB作为其后台调试工具。从Xcode 3.1开始,Xcode也可被用为iPhone OS的开发环境。Xcode 4.0于日正式发行。该版本非Apple开发者注册会员亦能从Mac App Store中付费下载, 收取US$4.99的费用。从Xcode 4.1开始,针对OS X 10.6及OS X 10.7用户从Mac App Store免费下载Xcode主要版本是Xcode 5,支持iOS7,可以在Mac App Store免费下载,亦可在iOS开发者计划网站下载。Xcode最新版本是Xcode 6,整合了苹果在WWDC大会上发布的新语言Swift。根据斯诺登提供的资料,美国政府研究人员创建了一个版本的苹果软件应用开发工具Xcode,希望借此将监控后门植入到通过苹果应用商店App Store发布的应用程序中 苹果软件编程工具(Xcode MAC)的功能:完全支持Swift编程Xcode 6为开发者引入了一种全新的设计和开发应用的方式,深度支持Swift编程,开发者不仅能使用100%的Swift代码来创建一款崭新的应用,还可以向已存在的应用添加Swift代码或框架,并在Swift或Objective-C中查看文档。诸如“Jump to Definition”、“Open Quickly”等在Swift中均能很好地工作,甚至Objective-C的头定义在Swift语法中也能良好地呈现。实时的代码效果预览现在,开发者在使用Interface Builder设计界面时,能够实时地预览代码效果。当程序运行时,自定义对象将在设计时展现。当开发者修改自定义视图代码时,Interface Builder的设计画布则会自动更新,而无需任何的构建和运行操作。此外,其所包含的API还支持向IB Inspector添加参数来快速修改视图,甚至开发者还可以预先填充示例数据视图来让界面更加准确。而支持UIKit大小类的iOS脚本则能够让开发者为所有iOS设备开发单一的通用脚本,不仅能为特定的设备尺寸或方向进行行为选择,还可以保持接口的一致性,且易于维护。新增View Debugging功能Xcode 6实现了此前备受开发者期待的View Debuger。现在,调试应用UI就像单击那样简单,开发者可以轻而易举地看到为什么一个视图可能会被裁剪或隐藏,并在Inspector中检查和调试约束及其他参数。当然,Xcode还包含了其他新的调试工具,比如调试Gauge来监控I/O用法、增强版的iCloud Gauge等,而Debug Navigator也将显示更有用的信息,包括栈框架记录和块队列等。 快捷键编辑文件CMD + N: 新文件; CMD + SHIFT + N: 新项目; CMD + O: 打开;CMD + S: 保存; CMD + SHIFT + S: 另存为;CMD + W: 关闭窗口; CMD + SHIFT + W: 关闭文件编辑CMD + [: 左缩进;CMD + ]: 右缩进;CMD + CTRL + LEFT: 折叠;CMD + CTRL + RIGHT: 取消折叠;CMD + CTRL + TOP: 折叠全部函数;CMD + CTRL + BOTTOM: 取消全部函数折叠;CTRL + U: 取消全部折叠;CMD + D: 添加书签; CMD + /: 注释或取消注释;CTRL + .: 参数提示; ESC: 自动提示列表调试CMD + \: 设置或取消断点;CMD + OPT + \: 允许或禁用当前断点;CMD + OPT + B: 查看全部断点;CMD + RETURN: 编译并运行(根据设置决定是否启用断点);CMD + R: 编译并运行(不触发断点);CMD + Y: 编译并调试(触发断点);CMD + SHIFT + RETURN: 终止运行或调试;CMD + B: 编译;CMD + SHIFT + K: 清理;苹果软件编程工具(Xcode MAC)的特色:海量内存 Xcode 将赋予你创建诸如计算和渲染引擎应用程序的能力,这些应用程序使用64位内存定址。这非常适合数据集中的应用程序,其通过访问内存中的数据运行速度更快,远胜于磁盘访问。Xcode 将为你提供工具来建立并调试适合 Intel Core i5, i7 和 Mac OS X Lion 的 32 或 64 位应用程序,还可以让你创建包含32位和64位执行能力的 Fat Binaries。构建众所周知,在构建中引进多重处理器可以提高速度,Xcode 能帮你实现这个明显的结论。利用支持 Rendezvous 的分布式构建功能,可以轻易地把编译工作量分散到闲置的电脑上来寄放构建,或者更好是在单独的电脑上开发一个专门的 Xserve 构建寄放区,快速处理那些耗时的任务。JavaXcode 4 拥有众多功能,为 Java 开发人员赋予了更多的开发能力。利用改进的 Code Sense 索引及 Ant 项目模板,Java 用户可以继续使用他们的标准 Java 包,并构建具有 Xcode 关键生产功能的工具。Java 代码填充为你提供类别名、方法、变量及其他关键信息。在 Xcode 中创建 Java应用程序比以往更容易。 输入因为 Xcode 支持 CodeWarrior 风格相关项目参考,所以可以保证把 CodeWarrior 项目文件快速方便地转移到 Xcode。因为 Xcode 兼容 CodeWarrior 风格在线编码汇编,所以从 CodeWarrior 到 Xcode 转变的消耗得到降低, 也使得开发人员手动调整应用程序的临界性能部分。苹果电脑公司的 Mac OS X 综合开发环境Xcode 为各种类型的 Mac OS X软件项目提供项目编辑、搜索和浏览,文件编辑,项目构建和调试设备等功能。Xcode 可用来辅助开发应用程序、工具、架构、数据库、嵌入包、核心扩展和设备程序。Xcode 支持开发人员使用 C、 C++、Objective C、 AppleScript 和 Java。Xcode 能够和 Mac OS X 里众多其它的工具协作,例如综合用户界面结构应用程序;编译器如 gcc、javac 和jikes;还有调试工具如 gdb。另外,你可以用 AppleScript Studio 组增加一个 Aqua 界面到系统和应用程序脚本、命令行工具、以及网络应用程序中。以上三者无论如何都能在任何平台组合成最强大的脚本环境。远程调试 调试全屏幕应用程序(比如游戏)具有很大的挑战性。将调试窗口放在什么位置呢?有了 Xcode 2.0 的绘图远程调试,所有强大的 Xcode 调试功能(例如数据格式程序、Fix、Continue)都可以在远程机器上用来调试应用程序。利用与远程调试阶段的加密连接,Xcode 可以保证你的数据安全。 更新日志苹果软件编程工具(Xcode MAC) V6.4 中的新功能Xcode 6.4 adds support for iOS 8.4 Xcode 6.4 includes Swift 1.2 and SDKs for OS X 10.10 Yosemite and iOS 8.4 Xcode 7 includes Swift 2 and SDKs for iOS 9, watchOS 2, and OS X 10.11 El Capitan. Now you can go beyond the simulator to test your app on an iPad, iPhone, or Apple Watch — for free. Simply enter your Apple ID into the Accounts preference pane, then attach a device to your Mac using a Lightning cable. You can use the same Apple ID you already use for iCloud, iTunes, or the App Store, or create a new one. Join the Apple Developer Program when you’re ready to distribute or submit your apps to the App Store.(已解决)Xcode 换电脑提示 Could not attach to pid:“XXXX”错误
时间: 07:21:51
&&&& 阅读:150
&&&& 评论:
&&&& 收藏:0
标签:&&&&&&&&&&&&&&&&&&&&&&&&&&&在运行项目时出现了如下错误 (基本上重新启动项目即可)
紧接着再次运行又没有问题了。
稍微查询了一下得知,这个问题并不是由我们的操作引起的,有时就会莫名其妙的出现,但是有一些不同的情况
下面列出如何解决这个错误成功运行项目
首先什么都不做再次运行,基本都不会再出现错误&如果还不行,那么就把手机重新插拔或者重启模拟器&还不行就重启Xcode&还不行就clean一下工程&还不行就重启系统标签:&&&&&&&&&&&&&&&&&&&&&&&&&&&原文:/luorende/p/6295945.html
&&国之画&&&& &&&&&&
&& &&&&&&&&&&&&&&
鲁ICP备号-4
打开技术之扣,分享程序人生!怎样创建一个Xcode插件(Part 2)
招聘信息:
原文:原作者:译者:译者注:原文使用的是xcode6.3.2,我翻译的时候,使用的是xcode7.2.1,经过验证,本部分中说的依然是有效的.在文中你可以学习到一系列的技能,非常值得一看.这些技能不单单只是用来创建插件,对你平时的调试等,也有非常大的帮助.欢迎你来到创建xcode插件教程的第二部分.在中,你已经了解了怎么通过NSNotification来窥探xcode的内部类,并且代码注入了其私有类DVTBezelAlertPanel,并且,你还添加了一个NSMenuItem菜单到xcode的菜单栏里,通过它来持久化是否开启我们自定义的插件Rayrolling的功能在这个教程中,你会在第一部分中创建的Rayrolling的基础上继续向前,如果你并没有在这之前阅读第一部分或者你想从本处开始,你可以下载.本章中,你将会通过深入了解一些可用的工具来进一步探索Xcode,利用你将会学到的新知识,来修改Xcode的标题栏,使标题栏改为展示Ray的某首歌的歌词。开始啦打开Xcode和Terminal(终端),并且将它俩都平铺在桌面上,这样你可以同时看到它们,方便后续的操作.(yohunl注:后文将会一面在Xcode上点击,一面观察终端控制台的输出,一旦发现我们需要的输出,就要立马停止终端控制台,所以,平铺在桌面上才便于你操作,否则,你就忙不过来啦)因为从上一章,你已经学会了从xcode运行一个xcode实例来创建插件和调试插件,所以我们换一种新的方式:你将会直接通过终端命令来使用LLDB来探索Xcode,你不用再像第一部分那样从一个Xcode启动另一个调试用的Xcode实例来探索Xcode是怎样工作的了.LLDB的BFF和DTraceDTrace是最好的探索Xcode的工具之一,它是一款相当优秀的调试工具,它是Instruments的基石.只要你了解怎么使用它,你将会发现它是非常有用的工具.首先,为了对其有个了解,我们需要一个使用DTrace的demo,就如同我们学习一门新语言时候,总是会通过一个Hello Worlddemo一样.那么开始吧… 创建一个脚本,它是用来保持所有以IDE开头的类的运行计数,并在每次你调用该特定类方法或者实例方法时,增加计数.在你退出脚本时候,DTrace将会转储这些数据.运行Xcode,然后,在Terminal的一个新窗口中,输入如下的脚本:sudo&dtrace&-n&'objc$target:IDE*::entry&{&@[probemod]&=&count();&}'&&-p&`pgrep&-xo&Xcode`虽然你键入命令后并不会看到任何的输出,但是DTrace已经在后台默默的生成了所有方法调用的踪迹(trace).回到Xcode,随便尝试一些操作.打开某些文件,随便做一些点击操作.回到Terminal,然后按Ctrl+C来结束脚本,脚本产生的内容将会输出到Terminal上 (只有在你Ctrl + C终止脚本后,才能在Terminal上看到脚本输出的内容)相当酷吧:),其实使用Dtrace,你可以做到很多事,但是我们的教程不会覆盖你想了解的DTrace的全部,相反的,我们提供一个快速的Dtrace语法的概述,它将会帮助你开始:1.Probe Description(探头说明,前序描述):由提供者(Provider),模块(Module),功能(Function),名字(Name)组成,它们由冒号分隔.省略它们中的任何一个,将会使Probe Description包含所有的匹配项.你可以使用 * 和 ? 操作符来做模式匹配.Provider:这个包含了一系列的类和方法,例如profile,fbt,或者io.在我们的教程中,主要使用objc来hookObjective-C的方法调用.Module:在OC语言中,这部分指示的是你希望观察的指定的类名Function:指示你希望观察的特定方法名Name:虽然根据你的Provider的不同,有不同的name值可选,但是你在此只需要使用entry或者retrun,来匹配函数的开始或者结束.你要了解,你可以使用$target关键字来匹配进程ID,也可以使用p或者c标志来指定target.2.Predicate(谓词部分): 可选的表达式,它是用来过滤哪些动作是满足条件的.你可以把它当做一个if语句的条件部分.3.Action(动作): 将要执行的操作.它可以只是简单的输出一些内容到控制台,也可以是执行一个高级功能.就如同LLDB的命令image lookup -rn {Regex Query}一样,你也可以使用l标志来转储(dump)特定进程中的类和方法.为了演示这点,我们来看这样一个简单的例子,运行Safari,然后在终端输入以下脚本sudo&dtrace&-ln&'objc$target::-*ecret*:entry'&-p&`pgrep&-xn&Safari`上述的DTrace脚本会打印出所有的名字中包含ecret字符串的实例方法.因为Probe Description部分 提供了Name参数entry,所有的方法都有entry和return,所以基本上忽略了所有的重复查询请求.注意:如果你想掌握更多的Dtarce知识,你可以参考和.如果并没有理解所有的这篇快速介绍中介绍的内容,也不需要沮丧,因为Dtrace是一个相当复杂的工具.现在你了解到Dtace的最基本的内容,我们可以开始使用它来寻找我们感兴趣的NSViews了.因为Xcode含有大量的Views,你会发现,使用LLDB来试图找出它们,让你不堪重负.即使结合LLDB的条件断点,调试一些应用程序都包含的共同东西,也是一个丑陋的过程.幸运的是,使用Dtrace,将能带给你对付此类问题的巨大的帮助.你将会使用DTrace来找出Xcode中组成标题栏的视图(NSViews).(⊙o⊙)…….那么该怎么做呢?这是一种方法:当鼠标停止在,或者点击一个NSView,hitTest:方法将会被触发,这个方法将会返回在这个鼠标点下最深的子视图.你可以使用DTrace来顺着hitTest:方法来确定视图,那个你应该进一步探索其其父视图和子视图的视图.在终端中输入以下脚本:sudo&dtrace&-qn&'objc$target:NSView:-hitTest?:return&/arg1&!=&0/&{&printf("UIView:&0x%x\n",&arg1);&&}'&-p&`pgrep&-xo&Xcode`一旦这段脚本运行,请确定你的Xcode是第一响应者(通过在Xcode上任何地方点击一下即可成为第一响应者).在Xcode的窗口上移动你的鼠标指针,当你停止移动鼠标指针的时候,Dtrace将会输出一个内存地址多次,这是因为 hitTest: 被在视图层次上的多个视图调用.定位到Xcode的标题栏,点击标题栏.选择出现在终端中最近的地址,拷贝到你的粘贴板中打开一个新的终端窗口标签,运行LLDB,并将其附着到Xcode上,然后输出从DTrace中拷贝出的地址,像以下这样操作:>&lldb
(lldb)&pro&attach&-n&Xcode
(lldb)&po&{上一步拷贝到粘贴板中的对象地址,例如是0x7fcc2687cd40,则该命令是&po&0x7fcc2687cd40}
...其中,pro 是 progress的缩写,LLDB使用的是前序匹配原则,在不引起歧义的情况下 process,proc,proce都是可以的.在下面你还会看到 pro at -n Xcode这种写法,都是因为这个原则,都是等效的. pro attach -n Xcode ,使用attach命令直接在LLDB中把一个正在运行的进程连接到LLDB中,以便于进行动态调试.也就是说这个命令直接可以将LLDB添加到任意的其它不是由它自己创建的进程中!!你将会看到和以下相似的输出:注意:现在,Xcode被我们通过终端输入的LLDB命令所暂停了.你可以在任何时候通过输入process interrupt或者其缩写pro i来暂停Xcode,从而能够开始调试Xcode.另外,你也可以通过在任何时候输入continue或者缩写c来恢复Xcode的运行.请确定你总是了解附着于Xcode上的LLDB的状态,你可以认为,当Xcode被你的调试LLDB所暂停时候,它是不能够相应你的单击等操作的(如同你在Xcode中打了断点,调试的时候进入到断点一样)取决于你在Xcode中点击的地方,你可能会命中一系列的视图.探索这些内存地址的父视图(通过在lldb中 po [对象地址 supview])或者子视图(po [对象地址 subvies]),直到你得到了视图 IDEActivityView.一旦你找到了IDEActivityView,怎样确定这个视图就是你所希望找寻的视图呢?通过在LLDB中输入以下命令:(lldb)&po&[{找到的IDEActivityView实例的地址}&setHidden:YES]&&在我的机子上是&&po&[0x7fcc&setHidden:YES]
...这里的点表示我们省略了lldb的某些不重要的输出.
...如果是我们所期望的那个标题视图,那么现在Xcode的标题栏就被隐藏了,这就能证实它的确是我们所期望的标题栏的视图啦.通过如下命令来重新显示它:(lldb)&pro&i
(lldb)&po&[{找到的IDEActivityView实例的地址}&setHidden:NO]&&比如在我的机子上是&&po&[0x7fcc&setHidden:NO]
(lldb)&c以下这个图是上述在LLDB中输入命令的gif动画,供你参考:按照以往的经验,你知道,当你Build或者Stop一个Xcode工程的时候,标题栏视图的内容将会变化.你可以用DTrace来观察相关的函数.IDEActivity前缀是一个独特的命名约定,你可以观察所有的以IDEActivity开头的类,以此来观察在这幕后的所有相联系的事情.回到终端,通过Control + C来停止DTrace,然后输入以下命令到终端中:sudo&dtrace&-qn&'objc$target:IDEActivity*::entry&&{&printf("%c[%s&%s]\n",&probefunc[0],&probemod,&(string)&probefunc[1]);&@num[probemod]&=&count();&}'&-p&`pgrep&-xn&Xcode`这段脚本将会输出所有类名前缀是IDEActivity的所有方法调用.一旦你停止这个脚本命令(Control+C),它还会输出指定类方法的被调用次数.yohunl备注: 当你输入这个命令的时候,可能会遇到译者遇到的这种情况yohunldeMacBook-Pro:~ yohunl$ sudo dtrace -qn 'objc$target:IDEActivity*::entry &{ printf("%c[%s %s]\n", probefunc[0], probemod, (string)&probefunc[1]); @num[probemod] = count(); }' -p `pgrep -xn Xcode`dtrace: invalid probe specifier objc$target:IDEActivity*::entry &{ printf("%c[%s %s]\n", probefunc[0], probemod, (string)&probefunc[1]); @num[probemod] = count(); }: probe description objc50360:IDEActivity*::entry does not match any probes当遇到这种情况不要担心,不要茫然,你只要完全退出Xcode,再重新启动Xcode,再输入这个命令就好了.开始这个DTrace命令,回到Xcode中,随便打开一个工程,编译并运行,然后再停止.注意观察Xcode的标题栏的内容变化,然后停止Dtrace命令,查看结果:仔细分析上面输出的信息.IDEActivityView和其它类之间是怎么运转的都在控制台的输出信息中,但是也有大量的其它信息夹杂在其中(控制台的输出信息中),不是么?幸运的是,你可以有选择的限制展示给你的信息量.通过浏览相关的类,来确定是否有值得你进一步选择性探索的内容….,也许 IDEActivityReport* 就是一个不错的候选类,因为以它开头的类看起来就是有联系的(在我们上述的操作中,最后在DTrace看到的很多都是它,所以我们有理由觉得它就是有联系的).修改Dtrace脚本,使他看起来如下:sudo&dtrace&-qn&'objc$target:IDEActivityReport*::entry&&{&printf("%c[%s&%s]\n",&probefunc[0],&probemod,&(string)&probefunc[1]);&@num[probemod]&=&count();&}'&-p&`pgrep&-xn&Xcode`再运行,停止Xcode的动作的同时,密切关注控制台的输出信息.一旦停止Xcode,立马Control+C停止掉Dtrace的脚本,是否出现了一些类,看起来是值得我们进一步去探索的呢?IDEActivityReportStringSegment看起来比较值得探索.缩小我们的脚本的搜索范围,聚焦到这个类上来,注意以下命令的变化,注意Probe的Function部分的变化(我们上面分析了Dtrace命令的组成,其中Probe部分有个Function组成部分)sudo&dtrace&-qn&'objc$target:IDEActivityReportStringSegment::entry&&{&printf("%c[%s&%s]\n",&probefunc[0],&probemod,&(string)&probefunc[1]);&@num[probefunc]&=&count();&}'&-p&`pgrep&-xn&Xcode`通过编译,运行,停止Xcode工程;再一次停止Dtrace命令,观察IDEActivityReportStringSegment类的实例的方法各自被调用的次数(当Control+C停止命令后,在控制台会输出各个方法的调用次数).看起来,initWithString:priority:frontSeparator:backSeparator: 和 initWithString:priority:值得进一步分析!打开一个新的LLDB会话(打开一个终端标签页面,lldb进入LLDB),然后再运行如下命令:(lldb)&pro&attach&-n&Xcode
(lldb)&rb&'IDEActivityReportStringSegment\&initWithString'
Breakpoint&9:&2&locations.
(lldb)&br&command&add
Enter&your&debugger&command(s).&&Type&'DONE'&to&end.
>&po&NSLog(@"customidentifier&%s&%@",&$rsi,&$rdx)&
(lldb)&c在上面这段命令中,你添加了自定义的命令,当任何属于IDEActivityReportStringSegment类的以initWithString方法开头的方法被调用时,就会执行添加的自定义命令.它输出IDEActivityReportStringSegment实例的方法的 Selector 和 self (还记得教程一中提到的各个寄存器中存放的内容了吧)到控制台.另外,使用了customidentifier 来标识 NSLog的输出信息,这样你可以更容易的从控制台的输出中容易的定位到这些Log.回到终端,新建一个终端tab(使用快捷键 command&+ t ),建立一个customidentifier的grep尾搜索:tail&-f&/var/log/system.log&|&grep&customidentifier译者注,这句话输入后,并没有输出,当你切换到Xcode中,编译,运行,就产生输出了编译,运行Xcode,以便让Xcode产生IDEActivityReportStringSegment变化.下面的gif动画,显示了上面所说的所有你输入到LLDB中的命令,看起来如下:比较控制台的输出和Xcode的标题栏的输出,你可以明确的得到:它就是你要寻找的内容!!到使用Swizzle的时候了创建一个Objective-C的类NSObject的category,命名为Rayrolling IDEActivityReportStringSegment添加下面的代码到建立的文件 NSObject+Rayrolling_IDEActivityReportStringSegment.m:中:#import&"NSObject+Rayrolling_IDEActivityReportStringSegment.h"
#import&"NSObject+MethodSwizzler.h"
#import&"Rayrolling.h"
@interface&NSObject&()
-&(id)initWithString:(id)arg1&priority:(double)arg2&frontSeparator:(id)arg3&backSeparator:(id)arg4;
@implementation&NSObject&(Rayrolling_IDEActivityReportStringSegment)
+&(void)load
&&static&dispatch_once_t&onceT
&&dispatch_once(&onceToken,&^{
&&&&[NSClassFromString(@"IDEActivityReportStringSegment")&swizzleWithOriginalSelector:@selector(initWithString:priority:frontSeparator:backSeparator:)&swizzledSelector:@selector(Rayrolling_initWithString:priority:frontSeparator:backSeparator:)&isClassMethod:NO];
-&(id)Rayrolling_initWithString:(NSString&*)string&priority:(double)priority&frontSeparator:(id)frontSeparator&backSeparator:(id)backSeparator
&&static&NSArray&*
&&static&NSInteger&index&=&0;
&&static&dispatch_once_t&onceT
&&dispatch_once(&onceToken,&^{
&&&&lyrics&=&@[@"Never&gonna&live&you&up.",
&&&&&&&&&&&&&&&@"Never&gonna&set&you&down."];
&&index&=&index&>=&lyrics.count&-1&?&0&:&index&+&1;
&&if&&([Rayrolling&isEnabled])&{
&&&&return&[self&Rayrolling_initWithString:lyrics[index]&priority:priority&frontSeparator:frontSeparator&backSeparator:backSeparator];
&&return&[self&Rayrolling_initWithString:string&priority:priority&frontSeparator:frontSeparator&backSeparator:backSeparator];
@end下面是对上面代码的一些解释:你需要前向声明私有类的初始化方法initWithString:priority:frontSeparator:backSeparator:,否则编译器直接就让你通过不了.load是通常被用来初始化添加swizzle代码的地方.因为你使用一个category来交换方法,在category中建立实例变量是稍微有些复杂的.你可以通过associated objects给一个已存在的类添加实例变量,但这个是你自己应该掌握的内容.在这里,我们直接使用一个static NSArray来保持一个对象继续存在,即使它所在的方法已经执行完毕了.您可以使用相同的static伎俩,使得index也如此。使用dispatch_once初始化歌词NSArray递增index,如果越界了,就重置它检测插件是否是可用状态,如果是,那就更改string参数,否则,使用默认的参数正如你所看到的,使用正确的工具可以帮助你快速定位你想要的东西.然而,要达到这个目的,却有不止一种方法 - 你将会发现,通过堆(heap)分析照样可以定位到你所感兴趣的内容通过堆(heap)来重新寻找IDEActivityView在本节中,你将会重新搜寻Xcode的IDEActivityView和IDEActivityReportStringSegment,你将会使用一种略微不同的方式来达到这一目的.到目前为止,你都是通过自上而下的方式来进行定位的:你先找到一个可能的class,然后以某种方式在内存中寻找它的一个实例对象,再查找它的成员方法和属性.其实,以相反的方向来进行,似乎也是可行的,就是沿着参考链从下而上去寻找目标对象,直到找到它.很幸运,Xcode中附带了一些Python脚本,让你能够做到这点!结束掉终端中所有的已存在的LLDB和Dtrace的会话,然后重启Xcode.开始一个新的Xcode和LLDB会话,再一次执行LLDB附着到Xcode上的命令,然后,添加下面的命令脚本:(lldb)&pro&at&-n&Xcode&
(lldb)&command&script&import&lldb.macosx.heap
"malloc_info",&"ptr_refs",&"cstr_refs",&and&"objc_refs"&commands&have&been&installed,&use&the&"--help"&options&on&these&commands&for&detailed&help.这个脚本加载了一系列非常有用的方法到LLDB进程中.malloc_info: 展示当前堆得对象的详细信息.尤其是结合MallocStackLogging环境变量的时候及其有用!ptr_refs: 给它一个堆空间中的一个内存地址,它可以找到指向这个内存地址的其它对象.cstr_refs: 参数类型是char * ,查找它在内存中出现的地方.objc_refs: 找到内存中指定的类的实例你可能想先了解了解最容易的objc_refs.在LLDB中,通过以下脚本来找寻所有的IDEActivityView类的实例变量:(lldb)&objc_refs&-o&IDEActivityView
Searching&for&all&instances&of&classes&or&subclasses&of&"IDEActivityView"&(isa=0x10fffe650)
0x00007faaee9cbf30:&malloc(&&&304)&->&0x7faaee9cbf30&IDEActivityView.DVTLayerHostingView.NSView.NSResponder.NSObject.isa
[IDEActivityView:&0x7faaee9cbf30](因识别问题,这里将尖括号替换为方括号)这个脚本输出了内存中所有的IDEActivityView类的实例.其中的 -o 参数表示输出对象,也就是会调用对象的 description 方法通过这个简单地额脚本,你就可以在内存中找属于指定类的的实例对象.这招也适用于继承于该对象的子类.yohunl备注:很遗憾,在我电脑上,这句怎么都查询不到(lldb)&objc_refs&-o&IDEActivityView
error:&libarclite_macosx.a(arclite.o)&failed&to&load&objfile&for&/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/arc/libarclite_macosx.a
error:&libarclite_macosx.a(arclite.o)&failed&to&load&objfile&for&/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/arc/libarclite_macosx.a
Searching&for&all&instances&of&classes&or&subclasses&of&"IDEActivityView"&(isa=0x10ada9328)试了很多次,都没能得到所期望的东西,但我相信这个方法是可以的通过上一步 objc_refs发现的内存地址,你可以采用如下的脚本来展开一个IDEActivityView实例的成员变量:(lldb)&malloc_info&-t&0x7faaee9cbf30
0x00007faaee9cbf30:&malloc(&&&304)&->&0x7faaee9cbf30&IDEActivityView.DVTLayerHostingView.NSView.NSResponder.NSObject.isa&(IDEActivityView)&*addr&=&{
&&DVTLayerHostingView&=&{
&&&&NSView&=&{
&&&&&&NSResponder&=&{
...这还不是它能做到的全部!你甚至可以用它,通过指定的内存地址来获得其它对象的引用:(lldb)&ptr_refs&&0x7faaee9cbf30
0x00007faaeed9a308:&malloc(&&&&16)&->&0x7faaeed9a300&+&8&&&&&
0x00007faaeedb4148:&malloc(&&&176)&->&0x7faaeedb4140&+&8&&&&&&IDEActivityViewBackgroundButton.NSButton.NSControl.NSView.NSResponder._nextResponder
0x00007faaeedb4190:&malloc(&&&176)&->&0x7faaeedb4140&+&80&&&&&IDEActivityViewBackgroundButton.NSButton.NSControl._aux.NSObject.isa
0x00007faaeedb4928:&malloc(&&&160)&->&0x7faaeedb4920&+&8&&&&&&NSView.NSResponder._nextResponder
...注意:这些命令,如果结合 im loo -rn {classmethod regex} 方式来查询,甚至可以帮助你快速的定位到,并且探查到在内存中存活的该类的所有实例.当然了,尝试之前,请确定你的LLDB还是暂停状态,否则的话,这些命令是不会起作用的.你设置可以更进一步,有一个环境变量MallocStackLogging,它可以在你初始化任何一个对象的时候用于栈(stack)回溯.虽然很多引用都可以指向同一个对象,但是它可以指出来,哪个才是这个对象的”最终拥有者”. 这段还要再分析一下由于上文的LLDB已经附着(attach)在xcode上,所以你要先杀掉Xcode进程,再通过带上MallocStackLogging环境参数的LLDB来重启它:(lldb)&pro&kill&
Process&65196&exited&with&status&=&9&(0x)
(lldb)&pro&launch&-v&MallocStackLogging=1&-n
Process&67920&launched:&'/Applications/Xcode.app/Contents/MacOS/Xcode'&(x86_64)注意:如果你比较懒,不断的杀掉LLDB/Xcode会话,launchctl是一个更加方便的启用环境变量MallocStackLogging的方式:launchctl&setenv&MallocStackLogging&1这个命令将通过launch创建的每一个进程的MallocStackLogging都设置成了true.所以你要记得,通过如下的命令来移除它们:launchctl&unsetenv&MallocStackLogging为了测试上面的内容,首先,确保你的Xcode的Edit菜单下的菜单项是 如下图所示的 Enable Rayrolling :现在,打开任何一个Xcode工程,保证源码编辑窗口是打开的,编译,运行工程.伴随着工程的运行,你将会看到在编译完成和运行完成的时候,IDEActivityView(假装你不知道此时此刻,谁调用它)改变它的内容.暂停执行这个Xcode工程,如果需要,使用下面的命令来重新加载LLDB的heap(堆)方法集:(lldb)&pro&i&
(lldb)&command&script&import&lldb.macosx.heap
"malloc_info",&"ptr_refs",&"cstr_refs",&and&"objc_refs"&commands&have&been&installed,&use&the&"--help"&options&on&these&commands&for&detailed&help.提醒:如果你对多次输入这个命令感到厌烦,你可以去网上了解下怎么在 ~/.lldbinit 方法中建立 command aliases (命令的别名,或者缩写).这个在 ~/.lldbinit 文件的内容,在每次创建一个LLDB的会话实例的时候,都会被加载.现在,使用cstr_ref方法,给它传递Xcode标题栏的字符串内容.举个例子,如果这个工程的名字叫Rayrolling,那么你的Xcode的标题栏上显示的应该是诸如:”Running Rayrolling : Rayrolling:”此类的字符串:(lldb)&cstr_ref&"Running&Rayrolling&:&Rayrolling"&
0xcb21d0:&malloc(&&&&32)&->&0x118cb21d0
0xae21:&malloc(&&&&48)&->&0x12079ae10&+&17&&&&&__NSCFString1&bytes&after&__NSCFString
0xa3bb3:&malloc(&&&&64)&->&0x&+&35&&&&&__NSCFString19&bytes&after&__NSCFString
0x34d1:&malloc(&&&&48)&->&0x&+&17&&&&&__NSCFString1&bytes&after&__NSCFString
0x26a1:&malloc(&&&&48)&->&0x11f912690&+&17&&&&&__NSCFString1&bytes&after&__NSCFString正如你所看到的那样,主要的参考信息一般都是 NSString类型的参考,多数情况下,你并不能从字符串本身得到更多的信息.所以你可能想了解这样字符串是怎样被创建的?因为有MallocStackLogging,做到这点,相当容易!(lldb)&cstr_ref&"Running&Rayrolling&:&Rayrolling"&&-s这个脚本输出堆栈帧的信息,当这个char * 被创建的时候.通过所有的堆栈信息去跟踪实例变量,由于他们都是在内存中,内存地址的数量和其在内存中的相对位置都有可能不同,这些都取决于你和Xcode的互动方式的不同而不同.通过阅读分析堆栈的跟踪信息,你将会获得一组类,这些类就是负责Xcode中这方面的.举例来说,取决于你运行的这些LLDB查询命令,你可能会看到这些class,如: IDEActivityScrollingTextLayer , IDERunOperation , IDEActivityView 等等诸如此类的class.你还可以使用 ptr_ref 来作用于 cstr_ref 输出的信息,来看那些对象保留了这个string对象的引用.繁杂的随机探索技巧在Xcode中寻找正确的api是很复杂的,因为你是想在成千上万的类和方法中寻找符合条件的几个类而已.使用LLDB的正则表达式,可以帮助你更好的找到它们.某些时候,最好的获取信息的地方是代码中使用的单例(Singleton),查看Xcode中存在的单例,看看是否值得进一步深入的单例.当LLDB附着到Xcode,并且处于暂停状态时候,输入以下命令:(lldb)&i&loo&-rn&"\+\[IDE.*\&shared"这条命令将会查找以IDE开头的类名,并且以”shared”开头的类方法.这条命令等价于 target modules lookup -rn "\+\[IDE.*\ shared",-r是指后面的是正则表达式另外一个吸引力的替代方案是:(lldb)&i&loo&-rn&"\+\[[A-Za-z]*\&[A-Za-z]*\]"它将会输出所有的没有参数的类方法.正如你前面看到的,你可以很容易的找出你刚兴趣的类,通过给一个名字给上面提到的Python脚本,就可以搜索到.另外还有一个流行的工具,可以用来搜索类和类方法,这个工具的名字叫class-dump,它可以在 这里下载.它是LLDB命令im loo -rn {regex} 的另一种替代方式,因为它(Class-dump)可以输出更加整洁,清晰的头文件形式的输出.当然了,class-dump也有小缺点,它的缺点就是你必须限制你的搜索在指定的framework或者plugin中,而LLDB的image lookup 命令搜索的是整个的Xcode进程中的framework和plugin!也就是image lookup的搜索范围更大,更广.下一步该做什么?这里是第二部分最后完成的domo工程.在这个教程中,你学习到了最基本的DTrace技能,并且学习和使用了一些你可以得到的高级LLDB方法.如果你想了解更多的关于DTrace的知识,你可以阅读另一篇obcj.io上的优秀文章,还有就是官方的 DTrace文档在本系列教程的第三部分,我们将再一次关注 汇编,你将会学到另一种灵巧的工具,它的名字叫 Cycript.
微信扫一扫
订阅每日移动开发及APP推广热点资讯公众号:CocoaChina
您还没有登录!请或
点击量18161点击量14513点击量9643点击量8153点击量7873点击量7726点击量6914点击量6732点击量6343
&2016 Chukong Technologies,Inc.
京公网安备89}

我要回帖

更多关于 gdb attach 进程 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信