对象的使用

进程创建并使用内核对象用于完成工作。内存可以泄漏或误用(例如,释放后使用),处理内核对象可以泄漏或误用(例如,关闭后使用)。

句柄工具

为了帮助开发者诊断句柄问题可使用 handles 工具,下面是进程 29831(wlancfg.cmx )的简单使用:

  1. $ handles 29831
  2. handle koid rkoid rights type
  3. 0xa8d44a0f: 29973 0x0000d0ef vmo
  4. 0xa8e44aab: 29847 29846 0x0000f00e channel
  5. 0xa8d44a0b: 29972 0x0000d0ef vmo
  6. 0xa8e42413: 9931 9930 0x0000f00e channel
  7. 0xa8d44a07: 29971 0x0000d0ef vmo
  8. 0xa8f44a1f: 29969 29970 0x0000f00e channel
  9. 0xa8a44a3b: 29964 0x0000d0ef vmo
  10. 0xa8d44a17: 29962 29963 0x0000f00e channel
  11. 0xa8844a43: 29961 0x0000d0ef vmo
  12. 0xa8f44a4b: 29960 0x0000d0ef vmo
  13. 0xa8e44a3f: 29959 0x0000d0ef vmo
  14. 0xa8e44a23: 29958 0x0000800f port
  15. 0xa8f44a2f: 29957 0x0000d0ef vmo
  16. 0xa8644a53: 29911 0x0000d0ef vmo
  17. 0xa8a44a7f: 29908 0x0000d0ef vmo
  18. 0xa8844a6b: 29907 0x0000d0ef vmo
  19. 0xa8f44a63: 29906 0x0000d0ef vmo
  20. 0xa8844a6f: 29905 0x0000d0ef vmo
  21. 0xa8f44a8b: 29904 0x0000d0ef vmo
  22. 0xa8944a9f: 29903 0x0000d0ef vmo
  23. 0xa8444a83: 29900 0x0000800f vmar
  24. 0xa8e44a77: 29845 0x0000d0ef vmo
  25. 0xa8f44a8f: 1034 0x0000d0f7 vmo
  26. 0xa8d44aa3: 1129 0x0000d00b log
  27. 0xa8d44abf: 1129 0x0000d00b log
  28. 0xa8d44abb: 1129 0x0000d00b log
  29. 0xa8644aef: 29827 29828 0x0000f00e channel
  30. 0xa8844ac3: 29826 8711 0x0007dfcf job
  31. 0xa8144afb: 29825 29824 0x0000f00e channel
  32. 0xa8e44adb: 29816 29817 0x0000f00e channel
  33. 0xa8e44ad3: 29776 29777 0x0000f00e channel
  34. 0xa894496b: 29766 29767 0x0000f00e channel
  35. 0xa8d44a97: 29833 29831 0x0004d2cf thread
  36. 0xa8d44a93: 29832 0x0000801f vmar
  37. 0xa8d44aaf: 29831 29826 0x0006d3cf process
  38. 0xa8f44a73: 29850 0x0000d00b log
  39. 0xa8f44af3: 29768 29769 0x0000f00e channel
  40. 0xa8e44aa7: 29834 29835 0x0000f00e channel
  41. 38 handles

handles <pid> 工具打印出来进程句柄表,在指定的进程中引用瞬间列出了全部可访问的句柄。

对于每个句柄工具打印出句柄的值,权限和对象类型,对象的 koid。如果有相关的对象会打印出 rkoid。

在上面的例子中,显示了38个唯一的句柄,其中映射36个唯一对象。3个句柄指向相同的 1129「log」对象。

注意,并不是全部的存活的对象都可以通过工具显示出来。例如,一个存活的线程即使没有句柄打开它,VMOs 也可以通过关联的 VMAR 保持存活

handles 工具通过对象类型支持过滤和排除过滤。执行handles --help 可以看到全部的选项详情。

调试句柄

你可以使用 调试器 查看句柄信息。获取进程并运行 handles 命令,它就显示句柄值,对象类型和对象koid:

  1. [zxdb] handles
  2. 504103211 ZX_OBJ_TYPE_VMO 27851
  3. 504103271 ZX_OBJ_TYPE_VMO 27719
  4. 505151859 ZX_OBJ_TYPE_VMO 27720
  5. 505151867 ZX_OBJ_TYPE_VMO 27718
  6. 506200511 ZX_OBJ_TYPE_PORT 27976
  7. 507249163 ZX_OBJ_TYPE_VMAR 27716
  8. 508297363 ZX_OBJ_TYPE_VMO 28200
  9. 508297379 ZX_OBJ_TYPE_VMO 28187
  10. 508297387 ZX_OBJ_TYPE_SOCKET 28189
  11. 508297731 ZX_OBJ_TYPE_CLOCK 1263
  12. 508297735 ZX_OBJ_TYPE_LOG 1275
  13. 508297755 ZX_OBJ_TYPE_LOG 1275

你也可以通过调用 handle 指定的句柄值来查看关于句柄的基本信息:

  1. [zxdb] handle 508302371
  2. Type ZX_OBJ_TYPE_CHANNEL
  3. Value 508302371
  4. Rights ZX_RIGHT_TRANSFER
  5. ZX_RIGHT_READ
  6. ZX_RIGHT_WRITE
  7. ZX_RIGHT_SIGNAL
  8. ZX_RIGHT_SIGNAL_PEER
  9. ZX_RIGHT_WAIT
  10. ZX_RIGHT_INSPECT
  11. Koid 31062
  12. Related koid 31061

如果句柄引用的对象是关联到另一个对象(比如,管道的尾部或者父作业),related_koid 是其他对象的koid,如果这没有相关的其他对象,该值是零。在这个例子中,related_koid 是另一个管道尾部。这个关系是不可变的:一个对象的 related_koid 不能改变甚至如果关联对象不再存在了。

糟糕的句柄策略

关闭 后使用句柄或者已关闭的句柄再次关闭它会出现糟糕的诊断错误。

为了帮助开发者找到问题,「糟糕的句柄」作业策略可以通过 ZX_POL_BAD_HANDLEZX_POL_ACTION_ALLOW_EXCEPTION 来激活使用 Zircon作业设置策略。 当一个进程运行在这个策略的作业下,任何使用已经关闭的句柄会生成异常,如果没有句柄中断进程并记录调用栈或者通过调试器收集。