【问题标题】:Xcode attach to process doesn't display NSLogXcode附加到进程不显示NSLog
【发布时间】:2015-05-20 06:58:25
【问题描述】:

我刚刚开始使用 Apple Watch。我从“Five Minute Watchkit”中找到了关于让 iOS 应用程序和 watch kit 应用程序都在模拟器中运行并且两个进程都附加到 LLDB 调试器的说明。

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

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

这行得通。我可以在手表套件 InterfaceController 或我的 iOS 应用程序中设置断点,并且调试器会在应该的时候中断。

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

(顺便说一句,将操作附加到从断点调用 NSLog 的断点也不会显示,但会显示“日志消息”调试器命令。 有人有什么见解吗?)

编辑: iOS 应用程序中的代码似乎无关紧要。就我而言,这是一个简单的 IBAction,它附加到 iOS 应用故事板中的一个按钮:

- (IBAction)buttonAction:(UIButton *)sender;
{
  NSLog(@"Button clicked on iPhone");
}

我可以在那个 NSLog 语句上设置一个断点。调试器在该行停止,但我在调试控制台中看不到日志语句。

【问题讨论】:

  • 你确定编译器能做到这一点吗?哦,请显示一些代码,这会很有帮助
  • Linus,我很乐观。调试器在包含 NSLog 的行处中断。只是日志语句没有显示到控制台。
  • 第三次,调试器在相关行的断点处停止。我绝对 100% 确定连接是正确的。如果我在 Xcode 中使用 ⌘R 启动 iOS 应用程序,则日志语句有效。只有当我在 sim 中运行应用程序然后附加到正在运行的进程时,我的 NSLog 语句才无法显示。
  • 将 IBAction 的参数类型更改为 id 是在对问题挥舞着死鸡,甚至不值得尝试。

标签: ios objective-c xcode apple-watch


【解决方案1】:

我可以通过一个没有 WatchKit 的简单测试应用来重现这一点。该应用程序由一个 NSTimer 组成,它每秒打印“定时器触发”。 (此代码 100% 正确;)。手动附加到进程后,日志中没有显示任何内容。
据我所知,NSLog 输出到 stderr,我猜附加调试器不会将 stderr 重定向到 Xcode 终端。

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

您可以在终端中查看(catgreptail),也可以在 Console.app 中打开。


Apple 在Technical Note TN2239: iOS Debugging Magic 中确认了这一点(至少对于 GDB)。

控制台输出

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

  • 如果您启动一个 GUI 应用程序,它将由正常启动 用户,系统将打印在 stderr 上的任何消息重定向到 系统日志。您可以使用所描述的技术查看这些消息 早些时候。
  • 如果你在 Xcode 中运行一个程序,你可以看到它 Xcode 的调试器控制台窗口中的 stderr 输出(选择控制台 运行菜单中的菜单项以查看此窗口)。

附加到 运行程序(使用 Xcode 的附加到进程菜单,或附加 GDB 中的命令)不会自动将程序的 stderr 连接到 您的 GDB 窗口。 您可以使用该技巧在 GDB 中执行此操作 的“附加后查看标准输出和标准错误”部分中描述 技术说明 TN2030,“GDB for MacsBug Veterans”。

提到的 TN2030 在他们的服务器上不再可用 (mirror)。它展示了如何将 stdout 和 stderr 重定向到 Xcode 控制台。但是,由于shell tty 不是 LLDB 的有效命令,它不会有太大帮助。但也许有一种不同的方式来访问 tty Xcodes 控制台使用,所以我附上了那个 TN 的重要部分。

附加后看到stdout和stderr

如果您将 GDB 附加到进程(而不是启动进程 从 GDB 中),您将无法看到该过程的任何内容 打印到标准输出或标准错误。 Finder 启动的程序通常 将标准输出和标准错误连接到“/dev/console”,所以信息 他们打印到控制台。您可以通过启动 控制台应用程序(在 Utilities 文件夹中),但是,它是 不方便必须在单独的窗口中查看。另一种选择 是将进程的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 ...]

【讨论】:

  • 如果必须的话,我可以在控制台中查看我的日志输出,但这很糟糕。控制台很吵。系统进程不断向控制台发布对我来说毫无意义的消息。另外,Xcode 调试控制台就是为此而设计的。它应该显示正在运行的程序的输出。启动应用程序是一个多步骤过程:杀死手表应用程序、iOS 应用程序、构建和运行 iOS 应用程序、杀死它、启动手表应用程序、在 sim 中启动 iOS 应用程序、将调试器附加到 iOS 应用程序。说实话,这很痛苦。
  • MacsBug?!?哦,伙计,这可以追溯到 LOOOOONNNG 方式。那是在 Mac 使用 68000 系列处理器的时候。我在 80 年代末和 90 年代在我的 Mac II 上使用了 MacsBug。
  • 我应该在 FMW 帖子中添加一个关于此的注释。 :-)
  • 我要补充一点,如上所述,使用 grep 进行过滤很容易,只找到您的调试消息,因此您没有控制台噪音。
  • 这是一个真正令人困惑的问题,我整个上午都在网上搜索。每一个解释都会爆发成一个完全不相关的讨论。这是迄今为止唯一相关的答案。谢谢!
【解决方案2】:

要添加到 Filipp Keks 答案,这里有一个比接受的答案更简单的方法的视觉表示。

来自 Filipp Keks 的回答:

  1. 插入设备并打开Xcode

  2. 从菜单栏中选择窗口 -> 设备

  3. 在左列的“设备”部分下,选择设备

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

  5. 点击右下角的向下箭头将控制台保存为文件”

此屏幕截图是在 Xcode 7.3.1 的“设备”窗口中截取的。

【讨论】:

  • 我同意它对我来说在 Xcode 8.3.3 上的工作方式相同。必须记住,这是一个完整的调试日志,因此所有应用程序和服务都会出现在那里,您必须从您的进程中找到它们。
  • 如果你能过滤这些日志,那么“更简单”。但是 ATM(xcode 9.2) 你不能用这个 UI 做任何事情。 (至少在实时会话中)。无论如何,我找到了一个 github 项目 deviceconsole,它在 shell 中执行相同的操作,允许您按应有的方式进行过滤(有点不稳定,发生了几次崩溃:()有没有人知道一个更好的项目?
【解决方案3】:

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

  1. 同时杀死手机应用和手表应用
  2. 选择 Watch Extension Target 并点击 Cmd+R(构建并运行)
  3. 选择电话目标并点击 Ctrl+Cmd+R(无需构建即可运行)

在我的例子中,我在他们的模拟器中安装了这两个应用程序并获得了两者的 NSLog 输出。我不需要单独附加。希望这会有所帮助。

【讨论】:

  • 我得试试这个。感谢您在一个相当老的帖子上发帖。
  • 当我这样做时,它会停止我的手表应用程序并且手表会进入主屏幕。
【解决方案4】:

https://developer.apple.com/library/ios/qa/qa1747/_index.html

  1. 插入设备并打开Xcode

  2. 从菜单栏中选择窗口 -> 设备

  3. 在左列的“设备”部分下,选择设备

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

  5. 点击右下角的向下箭头将控制台保存为文件

【讨论】:

    【解决方案5】:

    当您的 Provisioning profile 设置为 AdHoc 或 Distribution 然后 Xcode 不显示日志,您需要设置开发才能查看日志

    【讨论】:

      【解决方案6】:

      这可能无法解决显示 NSLog 消息的问题,但在调试在后台启动的应用程序时可能会有所帮助。

      您可以使用允许您记录消息的断点功能。 这个想法是:

      • 创建一个选中“评估操作后自动继续”的断点
      • 添加“记录消息”操作(您也可以使用表达式并打印出值,例如:“记录消息@variable@”)
      • 使用预期的进程名称附加调试器(XCode 将等待进程启动)
      • 触发应用启动。

      学分和详细信息: https://fluffy.es/how-to-debug-app-which-got-launched-push-notification/

      【讨论】:

        【解决方案7】:

        在我的情况下,一组自动查看 NSLog,之前根本不显示

        【讨论】:

          【解决方案8】:

          我通过这个 (Xcode console empty after attaching to process) 提出了这个问题,该问题现已关闭。

          我的问题是 Xcode 中的调试控制台什么也没有显示(只是一个空的白框)。

          我的解决方案是底部的一个小开关,它在“变量视图”和实际调试控制台之间切换。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2012-07-17
            • 2014-02-07
            • 2021-06-09
            • 1970-01-01
            • 2015-11-14
            • 1970-01-01
            相关资源
            最近更新 更多