基本解释了最近在调试时遇到的一些疑问,接下来就是找解决方法了。

//-- Begin: 1

Sometimes when I'm debugging (OK, or hacking) something, a selector
that I know is implemented by one of the classes in the target project
is just not recognized by the debugger.  No tab-completion, etc.  Even
the class is not recognized.  Yet looking up a class object by
NSClassFromString and selector from NSSelectorFromString return
reasonable looking values.

Let's say I know a class "BobController" has a method "slackOff:" - I
get a SEL from NSSelectorFromString(@"slackOff:").  It returns 111300.
I examine memory at that location and sure enough, it looks like a
selector!  I set a conditional breakpoint on objC_msgSend, to break
whenever $r4==111300, and run the program.

A very slow launch later, I perform a user action to provoke that
method (in this case, a menu item that InterfaceBuilder shows as being
targeted to "BobController" with an action of "slackOff:").  No
breakpoint!

Is it unrealistic for me to assume that all messages will get sent
through objC_msgSend?  What is gdb doing when it sets a breakpoint on
an Objective C method symbol?  I guess I could look it up in the
source... any thoughts?

Daniel

//-- End

======================================================================================================

//-- Begin: 2

> Sometimes when I'm debugging (OK, or hacking) something, a selector
> that I know is implemented by one of the classes in the target project
> is just not recognized by the debugger.  No tab-completion, etc.  Even
> the class is not recognized.  Yet looking up a class object by
> NSClassFromString and selector from NSSelectorFromString return
> reasonable looking values.

the reason you're not able to break on an Objective-C symbol is most
likely because the binary in question has been stripped of debugging
symbols..  To see what I mean, compile your own Cocoa app, then run nm
on it and notice that all the objective-c symbols are plainly visible.
If you then run the strip command on the binary, then re-run nm,
you'll see that all the objective-c symbol information has been
removed.

It's important to note that even when a binary has been stripped, the
objective-c symbol information is still available from the objective-c
segment.  Unfortunately, gdb only relies on the symtab segment for
it's objective-c symbol parsing, so once this information has been
stripped, gdb can't set a breakpoint on an objective-c method.

You can, however, use otool to determine the method implementation
addresses to manually set a breakpoint on methods whose symbols have
been removed.  For example, to find the address of the method
"addAppointment:", you can do something like this: "otool -ov
<binaryname> | grep -A addAppointment:".  You'll then see something
like "method_imp 0x00008518".  You can then set a breakpoint in gdb on
this address.

Mike

//-- End

======================================================================================================

//-- Begin: 3

Thanks, Mike.  I will try the otool examination trick.

I can appreciate that the symbols have been stripped.  That explains
why gdb doesn't recognize the class or method names, but it doesn't
explain to me why I can't set a breakpoint on objC_msgSend to catch the
message, since that is unrelated to debugging symbols.

Daniel

//-- End

======================================================================================================

//-- Begin: 4

For anybody following along, there is a minor correction to make to
Mike's excellent advice below.

The "-A" option to grep requires an integer to specify how many lines
of context to display. In this case, it looks like 3 is the right
number to ask for if you want to see the method_imp entry:

otool -ov <binaryname> | grep -A 3 <methodName>

Thanks again, Mike!

Daniel

//-- End

======================================================================================================

//-- Begin: 5

There is an easy way to do this in the XCode debugger.  Bring up the
breakpoints window and create a new breakpoint.  Type [BobController
slackOff:].  Jonathan.

//-- End

======================================================================================================

//-- Begin: 6

You must have missed the part in my original message that said I am
working with methods that gdb doesn't recognize (no symbols).  That
being the case, Xcode has as much trouble setting the breakpoint as I
do.

My real question is "Why doesn't a conditional breakpoint on
objC_msgSend trap a method call with a particular SEL?"  The rest of
the details were for context only. This question is sort of beyond the
scope of Cocoa, I guess. I should probably raise it on the xcode list
if I want gdb nerds to respond :)

Daniel

//-- End

======================================================================================================

//-- Begin: 7

Is there a way to import the output from class-dump into GDB?

It’s possible to load a symbol file in gdb with the add-symbol-file command. The hardest part is to produce this symbol file.

With the help of libMachObjC (which is part of class-dump), it’s very easy to dump all addresses and their corresponding Objective-C methods. I have written a small tool, objc-symbols which does exactly this.

Let’s use Calendar.app as an example. If you try to list the symbols with the nm tool, you will notice that the Calendar app has been stripped:

$ nm -U /Applications/Calendar.app/Contents/MacOS/Calendar0000000100000000 T __mh_execute_header
0000000005614542-000000 OPT radr://5614542

But with objc-symbols you can easily retrieve the addresses of all the missing Objective-C methods:

$ objc-symbols /Applications/Calendar.app
00000001000c774c+[CALCanvasAttributedText textWithPosition:size:text:]00000001000c8936-[CALCanvasAttributedText createTextureIfNeeded]00000001000c8886-[CALCanvasAttributedText bounds]00000001000c883b-[CALCanvasAttributedText updateBezierRepresentation]...00000001000309eb-[CALApplication applicationDidFinishLaunching:]...

Then, with SymTabCreator you can create a symbol file, which is just actually an empty dylib with all the symbols.

Using objc-symbols and SymTabCreator together is straightforward:

$ objc-symbols /Applications/Calendar.app |SymTabCreator-o Calendar.stabs

You can check that Calendar.stabs contains all the symbols:

$ nm Calendar.stabs
000000010014a58b T +[APLCALSource printingCachedTextSize]000000010013e7c5 T +[APLColorSource alternateGenerator]000000010013e780 T +[APLColorSource defaultColorSource]000000010013e7bd T +[APLColorSource defaultGenerator]000000010011eb12 T +[APLConstraint constraintOfClass:withProperties:]...00000001000309eb T -[CALApplication applicationDidFinishLaunching:]...

Now let’s see what happens in gdb:

$ gdb --silent /Applications/Calendar.app
Reading symbols for shared libraries ................................. done

Without the symbol file:

(gdb) b -[CALApplication applicationDidFinishLaunching:]Function"-[CALApplication applicationDidFinishLaunching:]" not defined.Make breakpoint pending on future shared library load?(y or [n]) n

And after loading the symbol file:

(gdb) add-symbol-file Calendar.stabs
add symbol table from file "Calendar.stabs"?(y or n) y
Reading symbols from /Users/0xced/Calendar.stabs...done.(gdb) b -[CALApplication applicationDidFinishLaunching:]Breakpoint1 at 0x1000309f2

You will notice that the breakpoint address does not exactly match the symbol address (0x1000309f2 vs 0x1000309eb, 7 bytes of difference), this is because gdb automatically recognizes the function prologue and sets the breakpoint just after.

====================

I can't compile SymTabCreator, I get the error /Users/Tyilo/Downloads/SymTabCreator-master/SymTabCreator.m:80:54: Operand of type 'NSArray' where arithmetic or pointer type is required. – Tyilo Jul 25 at 17:07 

@Tyilo: You need to upgrade your developer tools. Xcode has supported object subscripting since 4.4. developer.apple.com/library/mac/releasenotes/ObjectiveC/… – Peter Hosey Jul 25 at 17:16

@PeterHosey Well I'm using Xcode 4.6, so there must be some build setting that prevents me from using objc subscripting. – Tyilo Jul 25 at 17:21

@PeterHosey It works fine when building the Debug version, but it only happens with the Release version. – Tyilo Jul 25 at 17:25

 Hey! Really nice code :) Like it a lot. I've created a script that simplifies all this into a single line. See gist.github.com/nickskull/6083359 – Dominik Hadl Jul 25 at 20:23

@Tyilo: I haven't looked, but it might be building both i386 and x86_64 architectures. The 64-bit build will succeed, on either configuration, but the 32-bit build will fail because subscripting (among other features) is 64-bit-only. Try unsetting the Architectures build setting. – Peter Hosey Jul 25 at 20:52

@PeterHosey That fixed it, thanks. – Tyilo

====================

//-- End

======================================================================================================

//-- Begin: 8

And now there is a way to do it... nice answer, 0xced!

The DWARF file format is well documented, IIRC, and, as the lldb source is available, you have a working example of a parser.

Since the source to class-dump is also available, it shouldn't be too hard to modify it to spew DWARF output that could then be loaded into the debugger.

Obviously, you wouldn't be able to dump symbols with full fidelity, but this would probably be quite useful.

===================

just to be clear … the original questioner was asking about gdb, but whether the original questioner ought to be more interested in lldb since that's what's current or else the original questioner really wants gdb, most of what is said here still stands … source to gdb can be retrieved from gnu.org/software/gdb/current if that's truly what's desired. –  john.k.doe Jul 21 at 17:35

@john.k.doe Yes -- good point. Also, it appears that gdb can load DWARF, as well. –  bbum

===================

//-- End

======================================================================================================

[整理]Breakpoint on arbitrary selector的更多相关文章

  1. CSS3 nth 伪类选择器

    考察下面的 HTML 代码片段: <div> <section>section 1</section> <section>section 2</s ...

  2. Android布局绘制常见小问题

    一些网上分享的整理 1.Android设置Selector不同状态下颜色及图片 Selector常用状态: android:state_selected 控件选中状态,可以为true或false an ...

  3. LLDB 和Chisel 使用例子

    打印变量 打印数字 (lldb) p/d 16 16 16 进制格式 (lldb) p/x 16 0x10 2 进制格式 (lldb) p/t 16 0b00000000000000000000000 ...

  4. Adding Cues (线索、提示) to Binary Feature Descriptors for Visual Place Recognition 论文阅读

    对于有想法改良描述子却无从下手的同学还是比较有帮助的. Abstract 在这个文章中我们提出了一种嵌入continues and selector(感觉就是analogue和digital的区别)线 ...

  5. [整理]Selector、shape详解

    Selector.shape详解(一) Selector的结构描述: <?xml version="1.0" encoding="utf-8"?> ...

  6. Python学习笔记整理总结【网络编程】【线程/进程/协程/IO多路模型/select/poll/epoll/selector】

    一.socket(单链接) 1.socket:应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口.在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socke ...

  7. iOS学习笔记-精华整理

    iOS学习笔记总结整理 一.内存管理情况 1- autorelease,当用户的代码在持续运行时,自动释放池是不会被销毁的,这段时间内用户可以安全地使用自动释放的对象.当用户的代码运行告一段 落,开始 ...

  8. iOS学习笔记总结整理

    来源:http://mobile.51cto.com/iphone-386851_all.htm 学习IOS开发这对于一个初学者来说,是一件非常挠头的事情.其实学习IOS开发无外乎平时的积累与总结.下 ...

  9. iOS之UI组件整理

    作者:神兽gcc 授权本站转载. 最近把iOS里的UI组件重新整理了一遍,简单来看一下常用的组件以及它们的实现.其实现在这些组件都可以通过Storyboard很快的生成,只是要向这些组件能够变得生动起 ...

随机推荐

  1. 怎样用OleDbDataAdapter来对数据库进行操作?

      请问怎样用OleDbDataAdapter来对数据库进行删除.改动和加入? OleDbDataAdapter是DataSet和数据源之间建立联系的重要纽带.用它我们能够对数据库进行删除.改动和加入 ...

  2. hdu1107武术(模拟题)

    Problem Description 在一个12行12方柱武侠世界,少林.武当峨眉武术弟子的三派,自相残杀主宰. 林世界的第一行的一列格子的坐标是(1, 1),第一行第二列坐标是(1, 2)--右下 ...

  3. Ubuntu14.04安装一个小问题,搜狗输入法

    罕见的搜狗输入法支持ubuntu.尝试了决定性下载. 官方网站:http://pinyin.sogou.com/linux/ 官网教程:http://pinyin.sogou.com/linux/he ...

  4. 玩转Vim-札记

    玩转Vim-札记 距上篇博文已有一周有余,上次主要介绍了编辑器之神Vim的起源.安装并介绍了两种模式以及一些简单的操作.本次将继续对Vim的使用进行介绍. 登堂入室 首先接着说移动吧: 1 0 → 数 ...

  5. The Swift Programming Language-官方教程精译Swift(6)控制流--Control Flow

    Swift提供了类似C语言的流程控制结构,包括可以多次执行任务的for和while循环,基于特定条件选择执行不同代码分支的if和switch语句,还有控制流程跳转到其他代码的break和continu ...

  6. IOS科研IOS开发笔记学习基础知识

    这篇文章是我的IOS学习笔记,他们是知识的基础,在这里,根据记录的查询后的条款. 1,UIScrollView能完毕滚动的功能. 示比例如以下: UIScrollView *tableScrollVi ...

  7. 【翻译自mos文章】SYS_OP_C2C 导致的全表扫描(fts)/全索引扫描

    SYS_OP_C2C 导致的全表扫描(fts)/全索引扫描 參考原文: SYS_OP_C2C Causing Full Table/Index Scans (Doc ID 732666.1) 适用于: ...

  8. HTML5实现涂鸦板

    原文:HTML5实现涂鸦板 最近闲的,看了看html5,强大的绘图功能让我惊奇,于是,写了个小玩意---涂鸦板,能实现功能有:画画,改色,调整画笔大小 html5的绘图可以分为点,线,面,圆,图片等, ...

  9. SqlDataReader的关闭问题

    原文:SqlDataReader的关闭问题 昨天一个朋友使用Repeater绑定数据源时,老是出现"阅读器关闭时尝试调用 FieldCount 无效."错误. 我看了他的代码,使用 ...

  10. 安卓CTS官方文档之兼容性测试套件简介

    官方英文文档原文:https://source.android.com/compatibility/cts-intro.html Compatibility Test Suite 兼容性测试套件 Ho ...