在Xcode 4.3中,现在您可以使用LLDB作为iOS目标的调试器.

与使用旧的GDB相比,它有什么优势?GDB仍然可以与LLVM一起使用,我在"日常"调试任务中看不到任何明显的差异.
我需要在我的iOS应用程序中显示HTML文本.我决定使用内置方法NSAttributedString,initWithData:options:documentAttributes:error:.实际的解析工作非常好,但是,我似乎遇到了一个非常奇怪的错误,如果我附加调试器,它似乎只会表现出来.
第一次调用此方法时,在运行iOS 7.0.4的iPhone 5S上运行时间不到1秒,在iPod Touch第5代上运行约1.5秒.这个怪癖也体现在模拟器上,但由于模拟器的绝对速度,它明显不那么引人注目.
后续呼叫只需要大约10-50毫秒,这比初始呼叫要快得多.
这似乎与输入字符串的缓存无关,因为我在我的"真实"应用程序中使用多个输入字符串对其进行了测试.
但是,当我在没有调试器的情况下运行程序时,它按预期运行,大约需要10-20ms,这是我希望HTML解析所采用的.
以下是相关的代码部分:
-(void) benchmarkMe:(id)sender {
NSData *data = [testString dataUsingEncoding:NSUTF8StringEncoding];
NSTimeInterval startTime = [[NSDate date] timeIntervalSinceReferenceDate];
// So the complier doesn't keep complaining at me.
__attribute__((unused))
NSAttributedString *parsed = [[NSAttributedString alloc] initWithData:data
options:@{
NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType,
NSCharacterEncodingDocumentAttribute: @(NSUTF8StringEncoding)
}
documentAttributes:nil
error:nil];
NSTimeInterval endTime = [[NSDate date] timeIntervalSinceReferenceDate];
NSString *message = [NSString stringWithFormat:@"Took %lf seconds.", endTime - startTime];
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Benchmark complete!"
message:message
delegate:nil
cancelButtonTitle:@"Ok"
otherButtonTitles:nil]; …Run Code Online (Sandbox Code Playgroud) 调试器真的(de)烦我.每当我尝试键入一个po ...命令时,它会自动填充(不给我任何选项)并且我最终会输入类似的内容po [selfelf,直到我发疯为止.有没有办法阻止这个,或者总是像标准编辑器一样给我自动完成弹出窗口?
注意:这个问题与从后台线程调用UIKit的警告有关,但没有给出下面两种方法的答案.
我有一个问题,应用程序屏幕快速闪烁.我过去已经遇到过这个问题,这是因为更新了主线程之外的UI元素.
因此,我将以下代码放在很多地方:
assertMainThread();
Run Code Online (Sandbox Code Playgroud)
这是:
#define assertMainThread() NSAssert([NSThread isMainThread],@"Method called using a thread other than main!")
Run Code Online (Sandbox Code Playgroud)
当然我无法使用assertMainThread()来覆盖整个代码,因为有很多地方和一些代码由背景GCD队列以合法的方式使用.
我看了很多地方,但找不到XCode或LLDB告诉我何时在主线程之外更新UI元素的方法.我认为可以使用符号断点或其他一些机制来破解UIKit中常见方法在主线程外部调用的地方,但是找不到方法.
我还以为UIKit可以在运行时发出警告吗?或者至少给我们一些工具来帮助调试这些问题.
我看过的另一种方法(但没有尝试)是使用一些代码覆盖技术,并尝试在视觉中提取代码中的哪个线程,但没有走那条路.
你对如何解决这个问题有任何想法吗?
我编写了一些代码,将类的所有ivars转储到Objective C中的字典中.这用于valueForKey:从类中获取数据.有时候,KVC会抛出一个也能正确捕获的内部异常 - 但这会破坏lldb的功能,而我得到的只是:
错误:执行被中断,原因:内部ObjC异常断点(-3)..进程已返回到表达式求值之前的状态.
没有设置断点.我甚至尝试使用-itrue -ufalse表达式选项,但它没有任何区别.这完全打败了我想要使用lldb的东西,它似乎是一个很小的问题.如果在调用方法时有内部的,捕获的ObjC异常,我怎么能把clang简单地忽略?
我在Xcode中尝试了这一点,直接通过从终端调用clang并连接到远程调试服务器 - 没有区别.
我的iOS应用程序中有一个带有dylib的框架,它是在另一台机器上编译的.我检查了我的机器lldb上的源代码,并尝试使用以下命令映射源代码路径:
settings set target.source-map /source/code/path/in/dylib/prefix /source/code/path/on/my/machine/prefix
Run Code Online (Sandbox Code Playgroud)
无济于事,仍然看到装配.
注意#1:dylib是在相同版本的Xcode中从C++代码编译的.
注意#2:我习惯于nm -pa /path/to/dylib确定文件路径是否嵌入到调试信息中,并且它们是lldb由于某种原因不能播放.
谢谢
UPDATE
我已经按照下面的Jim Ingham的回答创建了一个自动执行此脚本的脚本,该脚本在我撰写的文章中作为主要链接提供:https://medium.com/@maxraskin/background-1b4b6a9c65be
当我试图在其中运行Python解释器时lldb,我看到:
$ lldb
(lldb) script
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "/usr/local/Cellar/python/2.7.14/Frameworks/Python.framework/Versions/2.7/lib/python2.7/copy.py", line 52, in <module>
import weakref
File "/usr/local/Cellar/python/2.7.14/Frameworks/Python.framework/Versions/2.7/lib/python2.7/weakref.py", line 14, in <module>
from _weakref import (
ImportError: cannot import name _remove_dead_weakref
Python Interactive Interpreter. To exit, type 'quit()', 'exit()' or Ctrl-D.
Run Code Online (Sandbox Code Playgroud)
当我检查启动了哪个版本的Python时,Python报告它应该是Homebrew Python(它被符号链接到这个位置):
>>> sys.executable
'/usr/local/opt/python/bin/python2.7'
Run Code Online (Sandbox Code Playgroud)
但是,询问Python版本会返回与默认系统 Python安装相关联的版本,例如
>>> sys.version_info
sys.version_info(major=2, minor=7, micro=10, releaselevel='final', serial=0)
Run Code Online (Sandbox Code Playgroud)
并且,只是为了确认,上面的二进制路径上的Python版本确实不同(注意微版本的差异):
$ /usr/local/opt/python/bin/python2.7 --version
Python 2.7.14
$ /usr/bin/python --version
Python 2.7.10
Run Code Online (Sandbox Code Playgroud)
为了使事情变得更加混乱,名称_remove_dead_weakref 不 …
我正在使用lldb在Xcode 5中调试C++程序,我想在调试器中评估任意表达式,特别是那些使用重载运算符的表达式.
例如,我创建了一个非常简单的Xcode 5 C++项目,其中包含以下main.cpp和所有编译器/链接器/ etc选项设置为默认值:
#include <iostream>
#include <vector>
int main(int argc, const char * argv[])
{
std::vector<int> vec;
vec.push_back(42);
std::cout << "vec[0] = " << vec[0] << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我在线上设置断点return 0;并运行程序.
然后,在lldb提示符下,整个打印矢量工作正常:
(lldb) expr vec
(std::__1::vector<int, std::__1::allocator<int> >) $0 = size=1 {
[0] = 42
}
Run Code Online (Sandbox Code Playgroud)
但是,我无法使用重载访问其成员operator[]:
(lldb) expr vec[0]
error: call to a function 'std::__1::vector<int, std::__1::allocator<int> >::operator[](unsigned long)' ('_ZNSt3__16vectorIiNS_9allocatorIiEEEixEm') that is not present in the target
error: The expression could not …Run Code Online (Sandbox Code Playgroud) 我正在尝试调试我正在编写的C++程序,但是当我在LLDB中运行并停止程序时,它只显示汇编程序,而不是原始源代码.例如,崩溃之后我正在尝试调试:
Process 86122 stopped
* thread #13: tid = 0x142181, 0x0000000100006ec1 debug_build`game::update() + 10961, stop reason = EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
frame #0: 0x0000000100006ec1 debug_build`game::update() + 10961
debug_build`game::update:
-> 0x100006ec1 <+10961>: movq (%rdx), %rdx
0x100006ec4 <+10964>: movq %rax, -0xb28(%rbp)
0x100006ecb <+10971>: movq -0x1130(%rbp), %rax
0x100006ed2 <+10978>: movq 0x8(%rax), %rsi
Run Code Online (Sandbox Code Playgroud)
我正在编译-O0 -g.通过Xcode(我在OSX上)或从命令行运行调试器时,我看到同样的事情.
我还需要做些什么才能让源代码显示在LLDB中?
补充说明
以下是典型构建命令的示例:
clang++ -std=c++1y -stdlib=libc++ -fexceptions -I/usr/local/include -c -O2 -Wall -ferror-limit=5 -g -O0 -ftrapv lib/format.cpp -o format.o
Run Code Online (Sandbox Code Playgroud)
之前-O2是因为那是我正在使用的默认值,但我相信后者-O0会覆盖它,对吧?
我试过的
我用一个简单的'hello world'程序使用相同的构建设置重新创建了这个问题.
经过一些搜索,我试着运行dsymutil main.o …