Xcode附加到进程不显示NSLog

Dun*_*n C 25 xcode objective-c ios apple-watch

我刚刚开始使用Apple Watch.我发现了" Five Minute Watchkit "中的说明,即让iOS应用程序和监视工具包应用程序都在模拟器中运行,并且两个进程都连接到LLDB调试器.

我所做的是启动并退出iOS应用程序以在SIM中安装当前版本.然后我切换到watchKit方案并启动它,它在手表模拟器上显示我的手表应用程序UI.

然后我在模拟器中启动相应的iOS应用程序,然后用户在Xcode菜单中"附加到进程",将调试器附加到正在运行的iOS应用程序.

这有效.我可以在监视工具包InterfaceController或我的iOS应用程序中设置断点,调试器会在应用程序中断.

但是,我没有在我的iOS应用程序的调试控制台中看到NSLog()语句.(我确实看到来自WatchKit扩展代码的日志语句.)如果我在我的iOS应用程序中设置断点,它确实会在该断点处停止.我假设缺少来自NSLog的控制台输出有关SOMETHING与附加到sim上的正在运行的进程而不是从Xcode启动它,但我不知道那是什么.

(顺便说一句,将动作附加到从断点调用NSLog的断点也不会显示,但是"日志消息"调试器命令会显示.有人有任何见解吗?)

编辑:iOS应用程序中的代码似乎并不重要.就我而言,这是一个简单的IBAction,它附加在iOS应用程序故事板中的按钮上:

- (IBAction)buttonAction:(UIButton *)sender;
{
  NSLog(@"Button clicked on iPhone");
}
Run Code Online (Sandbox Code Playgroud)

我可以在NSLog语句上设置断点.调试器在该行停止,但我没有在调试控制台中看到日志语句.

Mat*_*uch 17

我可以用一个简单的测试应用程序重现它,没有WatchKit.该应用程序包含一个NSTimer,每秒打印"定时器触发".(此代码100%正确;).手动连接到进程后,日志中没有显示任何内容.
据我所知NSLog输出到stderr,我想附加调试器不会将stderr重定向到Xcode终端.

如果您可以使用控制台应用程序或终端查看日志,则可以执行此操作.iOS8存储模拟器日志~/Library/Logs/CoreSimulator/<Device-UUID>.在此目录中,您将找到一个system.log,其中包含您的所有NSLog输出.

你可以看看它在终端(cat,grep,tail),或在Console.app打开它.

在此输入图像描述


Apple在技术说明TN2239:iOS Debugging Magic中确认了(至少对于GDB而言).

控制台输出

许多程序,实际上是许多系统框架,都会向stderr打印调试消息.此输出的目标最终由程序控制:它可以将stderr重定向到它选择的任何目的地.但是,在大多数情况下,程序不会重定向stderr,因此输出将转到程序从其启动环境继承的默认目标.这通常是以下之一:

  • 如果您启动由普通用户启动的GUI应用程序,系统会将stderr上打印的任何消息重定向到系统日志.您可以使用前面介绍的技术查看这些消息.
  • 如果从Xcode中运行程序,您可以在Xcode的调试器控制台窗口中看到它的stderr输出(从Run菜单中选择Console菜单项以查看此窗口).

附加到正在运行的程序(使用Xcode的Attach to Process菜单或GDB中的attach命令)不会自动将程序的stderr连接到GDB窗口.您可以使用技术说明TN2030"GDB for MacsBug Veterans"中的"Seeing stdout and stderr After Attach"部分中描述的技巧在GDB中执行此操作.

提到的TN2030在他们的服务器(镜像)上不再可用.它展示了如何将stdout和stderr重定向到Xcode控制台.但是,由于shell tty它不是LLDB的有效命令,因此无济于事.但也许有一种不同的方式来访问tty Xcodes控制台使用,所以我附上了TN的重要部分.

在附加后看到stdout和stderr

如果将GDB附加到进程(而不是从GDB中启动进程),您将无法看到进程打印到stdout或stderr的任何内容.Finder启动的程序通常将stdout和stderr连接到"/ dev/console",因此它们打印的信息将发送到控制台.您可以通过启动控制台应用程序(在"实用工具"文件夹中)来查看此信息,但是,必须查看单独的窗口是不方便的.另一种方法是将进程的stdout或stderr连接到终端设备以获取GDB的终端窗口.清单9显示了如何执行此操作.

清单9.将stdout和stderr连接到GDB的终端设备.

(gdb) attach 795
[... output omitted ...]
(gdb) call (void) DebugPrintMenuList()
 No output )-:

 Close the stdout and stderr file descriptors.
(gdb) call (void) close(1)
(gdb) call (void) close(2)

 Determine the name of the terminal device for GDB itself.
(gdb) shell tty
/dev/ttyp1

 Reopen stdout and stderr, but connected to GDB's terminal.
 The function results should be 1 and 2; if not, something
 is horribly wrong.
(gdb) call (int) open("/dev/ttyp1", 2, 0)
$1 = 1
(gdb) call (int) open("/dev/ttyp1", 2, 0)
$2 = 2

 Try the DebugPrintMenuList again.
(gdb) call (void) DebugPrintMenuList()
 Yay output!
Index MenuRef     ID  Title
----- ---------- ---- -----
<regular menus>
00001 0x767725D3 -21629 Ed
00002 0x76772627 1128 <Apple>
00003 0x767726CF 1129 File
00004 0x76772567 1130 Edit
[... remaining output omitted ...]
Run Code Online (Sandbox Code Playgroud)

  • 如果必须的话,我在控制台中查看我的日志输出"ok",但很糟糕.控制台非常嘈杂.系统进程不断向控制台发布对我毫无意义的消息.此外,Xcode调试控制台专为此而设计.它应该显示正在运行的程序的输出.启动应用程序是一个多步骤的过程:杀死手表应用程序,iOS应用程序,构建和运行iOS应用程序,杀死它,启动监视应用程序,在sim中启动iOS应用程序,将调试程序附加到iOS应用程序.这是一种痛苦,说实话. (5认同)

mat*_*ode 12

要添加到Filipp Keks的答案,这里的视觉表示比接受的答案要简单得多.

来自Filipp Keks的回答:"1)插入设备并打开Xcode

2)从菜单栏中选择Window - > Devices

3)在左列的DEVICES部分下,选择设备

4)要查看设备控制台,请单击右侧面板左下角的向上三角形

5)单击右下角的向下箭头将控制台另存为文件"

此屏幕截图是在"设备"窗口的Xcode 7.3.1中拍摄的.

在此输入图像描述


Nik*_*att 6

使用Xcode Version 7.2和iOS 9.2等,我发现了以下工作:

0)杀死手机应用程序和观看应用程序
1)选择观看分机目标并点击Cmd+ R(构建并运行)
2)选择手机目标并点击Ctrl+ Cmd+ R(无需建设)

在我的情况下,我在他们的模拟器中有两个应用程序并获得两者的NSLog输出.我不需要单独附加.希望这可以帮助.

  • 当我这样做它停止我的手表应用程序,手表进入主屏幕. (2认同)