QNX常用调试方法

QNX常用调试方法

1. top

查询系统状态最常用的工具是top,它可以显示系统资源的使用情况。我们最关心的通常是系统可用内存和CPU使用率。如果CPU使用率过高可能是因为某些应用存在bug,重点关注下面显示的占用CPU资源最多的几个线程。如果可用内存太少,可能某些应用存在内存泄漏情况。但top工具无法显示占用内存最多的应用,我们可以使用另外一个工具hogs。

top工具截图

2. hogs

hogs工具和top类似,默认也是按照CPU使用情况对进程进行排序。但可以指定-S m参数使其按内存使用情况排序,这样就能揪出消耗内存最多的几个进程了。知道了哪个进程消耗内存最多,我们还是无法判断它是否存在内存泄漏,因为无法判断占用内存多的是哪部分。如果能看到该进程的Heap越来越大,才可以确认它存在内存泄漏。

hogs工具截图

3. pidin

锁定了嫌疑进程后就可以对其进行详细信息查询了。在QNX上查询进程信息最基本的工具是pidin,它类似Linux上的ps命令。这两个工具在QNX上都是基于proc文件系统实现的,但pidin比ps功能要更强大。pidin的命令行参数支持六十多种格式码,每个格式码代表一种信息,可任意组合。估计该工具的作者怕使用者记不住这么多参数,又提供了一些shorthand,就是一些预设的格式码组合。常用的有:arg用于显示进程参数,fds用于显示进程打开的连接和文件,user用于显示进程的用户信息等。pidin默认显示所有进程的信息,如只想查询指定进程信息,可用-p参数指定进程名或pid。

pidin工具截图

性能分析工具

有时调试进程不一定是因为应用存在逻辑bug,也可能是应用性能无法满足需求,例如处理某个函数耗时过长,或CPU占用率过高。这时就需要对应用进行性能分析,从而找到优化方案。这时可以考虑使用tracelogger。

1. tracelogger

如果想知道QNX内核在一段时间内都干了什么,最常用的工具就是tracelogger了。该工具可以将内核事件记录到.kev文件中进行分析。kev表示kernel event,包括系统调用、调度行为、中断处理以及进程和线程的创建、销毁和状态改变等等。这些事件都来自procnto*-instr,开始记录后内核会将事件信息保存到内存buffer中,每个buffer的大小为16KB,buffer数量由tracelogger设置,默认32个。记录完成后tracelogger会将buffer中的数据转储到指定的kev文件中。

手动启动tracelogger的方式比较灵活,可用-n参数指定buffer个数,当存满这么多buffer后就停止记录,如:

tracelogger -f /var/log.kev -n 12

也可以用-s指定时间,单位是秒,记录这么长时间后就停止,如:

tracelogger -f /var/log.kev -s 3

也可以用-r指定循环模式,记录过程buffer中的数据会循环覆盖,不会写入kev文件,直到用户按Ctrl+C才停止,然后将buffer中的数据写入文件。

tracelogger -f /var/log.kev -r -b 5

得到kev文件后可用traceprinter工具进行解析,也可以用Momentics IDE进行解析。traceprinter只是按顺序将内核事件解析成文本格式,不方便过滤分析,但这个工具是SDK自带的,无需额外购买license。Momentics IDE提供图形化解析工具,可过滤感兴趣的进程和事件,功能强大,使用方便,但需要购买license。

2. 进程监测工具

即使实验室中充分测试过的软件也无法保证在真实工况下不崩溃,毕竟物理世界有太多意想不到的情况。我们能做的只有在应用异常退出时,尽量自动恢复其功能。可以说进程监控工具是保障运行时功能的最后一道防线。QNX提供了两个工具可以监控进程,并在其异常退出时重启该进程,即SLM和HAM。下面简单介绍一下这两个工具。

1. SLM

SLM是System Launch and Monitor的缩写,用于启动和监控必须按指定顺序启动的复杂应用。SLM使用XML文件作为配置文件,将待启动的应用在xml文件中配置好,启动slm时指定该xml文件即可,如:

/bin/slm -V /slm/service_apps.xml

以下是slm配置文件的示例片段:

<SLM:component name="chime_service">
  <SLM:type>chime_service_t</SLM:type>
  <SLM:user>chime:iceoryx</SLM:user>
  <SLM:command launch="pathname">/bin/chime_service</SLM:command>
  <SLM:waitfor wait="pathname">/dev/chime_service</SLM:waitfor>
  <SLM:priority>10r</SLM:priority>
  <SLM:partition>aps_ic</SLM:partition>
</SLM:component>

<SLM:component name="ic_chime">
  <SLM:depend>chime_service</SLM:depend>
  <SLM:type>ic_apps_t</SLM:type>
  <SLM:user>ic_apps:iceoryx</SLM:user>
  <SLM:command launch="pathname">/usr/bin/ic_chime</SLM:command>
  <SLM:priority>10r</SLM:priority>
  <SLM:partition>aps_ic</SLM:partition>
  <SLM:stdout>/dev/slog2/stdout</SLM:stdout>
  <SLM:stderr iomode="a">/dev/slog2/stderr</SLM:stderr>
</SLM:component>

2. HAM

HAM是High Availability Manager的缩写,它能提供一种监控进程的机制。HAM的结构主要包括三部分:实体、条件、动作。每个被监控的进程都是一个实体,其下可注册多个条件,每个条件下可注册多个动作。一旦被监控的进程满足预设的条件,即可执行相应的动作。所有注册到HAM的实体都可以在/proc/ham目录下看到其状态。

下面是一个将进程本身注册到HAM的示例代码片段:

static int32_t attach_self_to_ham() {
  ham_entity_t *ehdl;
  ham_condition_t *chdl;
  ham_action_t *ahdl;

  /* attach to

 High Availability Manager */
  if (ham_attach_self(HAM_ENTITY_PROC, "pidin", &ehdl)) {
    fprintf(stderr, "Failed to attach to HAM");
    return -1;
  }

  /* create the conditions */
  if (ham_condition_create(ehdl, HAM_COND_USER, HAM_COND_OP_EQ, "root", &chdl)) {
    fprintf(stderr, "Failed to create the condition");
    ham_detach(ehdl);
    return -1;
  }
  ...
  /* create the actions */
  if (ham_action_create(ehdl, HAM_ACT_RESTART, "/bin/pidin -f", &ahdl)) {
    fprintf(stderr, "Failed to create the action");
    ham_detach(ehdl);
    return -1;
  }

  return 0;
}
  • 19
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

橘色的喵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值