gdb中的nil没有被定义为0x0? [英] nil in gdb is not defined as 0x0?
问题描述
我正在用gdb(Xcode内部)介绍一些简单的Objective-C代码,并注意到一些奇怪的东西。这里是相关的片段:
NSString * s = nil;
int x =(s == nil);
正如我所料, x
在这两行之后是 1
。奇怪的是,如果我在gdb中尝试类似的方法,它的工作方式不一样:
(gdb)print ret
$ 1 =(NSString *)0x0
(gdb)print(int)(ret == nil)
$ 2 = 0
(gdb)print nil
$ 3 = {<文本变量,无调试信息>} 0x167d18< nil>
似乎gdb除了objective-C使用的(0x0)之外还有一些零的定义。有人可以解释一下这里发生了什么吗?
当你的代码被编译时, nil
是一个预处理器常量,定义为 __ null
(一个特殊的GCC变量,用作 NULL
), 0L
或 0
: < objc / objc.h>
#ifndef nil
#define nil __DARWIN_NULL / * id为无实例* /
#endif
< sys / _types.h>
#ifdef __cplusplus
#ifdef __GNUG__
#define __DARWIN_NULL __null
#else / *! __GNUG__ * /
#ifdef __LP64__
#define __DARWIN_NULL(0L)
#else / *!__ LP64__ * /
#define __DARWIN_NULL 0
#endif / * __LP64__ * /
#endif / * __GNUG__ * /
#else / *! __cplusplus * /
#define __DARWIN_NULL((void *)0)
#endif / * __cplusplus * /
因此,gdb在运行时拾取的 nil
来自哪里?您可以从消息中得知gdb给出的 nil
是位于该地址的变量的名称:
(gdb)p nil
$ 1 = {<文本变量,无调试信息>} 0x20c49ba5da6428< nil>
(gdb)i addr nil
在没有调试编译的文件中,符号nil位于0x20c49ba5da6428处。
其值不出所料,结果是 0
:
(gdb)p *(long *)nil
$ 2 = 0
(gdb )x / xg nil
0x20c49ba5da6428< n> ;: 0x0000000000000000
这个变量来自哪里从? GDB可以告诉我们:
(gdb)我共享nil
3基金会F - init YY / System / Library / Frameworks / Foundation.framework / Versions / C / Foundation at 0x20c49ba5bb2000(offset 0x20c49ba5bb2000)
的确,当我们检查基金会中定义的符号,我们发现 nil
:
$ nm -m /System/Library/Frameworks/Foundation.framework/Foundation | grep nil
00000000001f4428(__TEXT,__ const)external _nil
I was stepping through some simple Objective-C code with gdb (inside of Xcode) and noticed something strange. Here is the relevant snippet:
NSString *s = nil;
int x = (s == nil);
As I'd expect, the value of x
after these two lines is 1
. Strangely, if I try something similar in gdb, it doesn't work the same:
(gdb) print ret
$1 = (NSString *) 0x0
(gdb) print (int)(ret==nil)
$2 = 0
(gdb) print nil
$3 = {<text variable, no debug info>} 0x167d18 <nil>
It seems like gdb has some definition for nil other than what objective-C uses (0x0). Can someone explain what's going on here?
When your code is being compiled, nil
is a preprocessor constant defined to be either __null
(a special GCC variable that serves as NULL
), 0L
, or 0
:
<objc/objc.h>
#ifndef nil
#define nil __DARWIN_NULL /* id of Nil instance */
#endif
<sys/_types.h>
#ifdef __cplusplus
#ifdef __GNUG__
#define __DARWIN_NULL __null
#else /* ! __GNUG__ */
#ifdef __LP64__
#define __DARWIN_NULL (0L)
#else /* !__LP64__ */
#define __DARWIN_NULL 0
#endif /* __LP64__ */
#endif /* __GNUG__ */
#else /* ! __cplusplus */
#define __DARWIN_NULL ((void *)0)
#endif /* __cplusplus */
So, where does the nil
that gdb picks up at runtime come from? You can tell from the message gdb gives that nil
is the name of a variable located at that address:
(gdb) p nil
$1 = {<text variable, no debug info>} 0x20c49ba5da6428 <nil>
(gdb) i addr nil
Symbol "nil" is at 0x20c49ba5da6428 in a file compiled without debugging.
Its value, unsurprisingly, turns out to be 0
:
(gdb) p *(long *)nil
$2 = 0
(gdb) x/xg nil
0x20c49ba5da6428 <nil>: 0x0000000000000000
Where does this variable come from? GDB can tell us:
(gdb) i shared nil
3 Foundation F - init Y Y /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation at 0x20c49ba5bb2000 (offset 0x20c49ba5bb2000)
Indeed, when we check the symbols defined in Foundation, we find nil
:
$ nm -m /System/Library/Frameworks/Foundation.framework/Foundation | grep nil$
00000000001f4428 (__TEXT,__const) external _nil
这篇关于gdb中的nil没有被定义为0x0?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!