trace中线程信息

Sample

Get trace info from /data/anr:
"main" prio=5 tid=1 Native
  | group="main" sCount=1 ucsCount=0 flags=1 obj=0x7161e500 self=0xf1e40e00
  | sysTid=878 nice=0 cgrp=background sched=0/0 handle=0xf22b6470
  | state=S schedstat=( 1446741865 981289649 3627 ) utm=94 stm=50 core=3 HZ=100
  | stack=0xff4e9000-0xff4eb000 stackSize=8188KB

各字段含义

  • Thread’s information format – first line

    • name – Thread name
    • priority – Thread priority
    • tid – Thread ID
    • status – Thread status
  • Thread’s information format – second line:

    • group – Group name,
    • sCount – Suspend count,
    • dsCount – Debug suspend count,
    • obj – Linux thread that we are associated with
    • self – Self reference
  • Thread’s information format – third line:

    • sysTid – Linux thread ID
    • nice – Linux “nice” priority (lower numbers indicate higher priority)
    • sched – Scheduling priority
    • cgrp – Scheduling group buffer
    • handle – Thread handle
  • Thread’s information format – fourth line

    • Schedstat: This is CPU schedule statics data:
      • Running time: CPU running time, unit: ns.
      • Runnable time: RQ queue waiting time, unit: ns.
      • Switch number: CPU scheduler switch times.
    • utm: Thread run in user space time, unit: jiffies. jiffies defined by “sysconf(_SC_CLK_TCK)”. The default value is 10ms.
    • stm: Thread run in kernel space time, unit: jiffies. The default value is 10ms.

线程状态

对应上面trace信息中的Native的位置。

  • ZOMBIE − terminated thread
  • RUNNABLE − runnable or running now
  • TIMED_WAIT − timed waiting in Object.wait()
  • MONITOR − blocked on a monitor
  • WAIT − waiting in Object.wait()
  • INITIALIZING − allocated, not yet running
  • STARTING − started, not yet on thread list
  • NATIVE − off in a JNI native method
  • VMWAIT − waiting on a VM resource
  • SUSPENDED − suspended, usually by GC or debugger
  • UNKNOWN − thread is in the undefined state

state

包括有 R、S、D、T、Z、X六个状态。

状态 含义
R TASK_RUNNING,可执行状态,包括正在运行和可运行两种状态
S TASK_INTERRUPTIBLE, 可中断的睡眠状态。处于这个状态的进程因为等待某某事件的发生(比如等待socket连接、等待信号量),而被挂起。这些进程的task_struct结构被放入对应事件的等待队列中。当这些事件发生时(由外部中断触发、或由其他进程触发),对应的等待队列中的一个或多个进程将被唤醒。
D TASK_UNINTERRUPTIBLE,不可中断的睡眠状态。TASK_UNINTERRUPTIBLE状态存在的意义就在于,内核的某些处理流程是不能被打断的。在进程对某些硬件进行操作时(比如进程调用read系统调用对某个设备文件进行读操作,而read系统调用最终执行到对应设备驱动的代码,并与对应的物理设备进行交互),可能需要使用TASK_UNINTERRUPTIBLE状态对进程进行保护,以避免进程与设备交互的过程被打断,造成设备陷入不可控的状态。
T TASK_STOPPED or TASK_TRACED,暂停状态或跟踪状态。 向进程发送一个SIGSTOP信号,它就会因响应该信号而进入TASK_STOPPED状态(除非该进程本身处于TASK_UNINTERRUPTIBLE状态而不响应信号)。(SIGSTOP与SIGKILL信号一样,是非常强制的。不允许用户进程通过signal系列的系统调用重新设置对应的信号处理函数。)向进程发送一个SIGCONT信号,可以让其从TASK_STOPPED状态恢复到TASK_RUNNING状态。当进程正在被跟踪时,它处于TASK_TRACED这个特殊的状态。“正在被跟踪”指的是进程暂停下来,等待跟踪它的进程对它进行操作。比如在gdb中对被跟踪的进程下一个断点,进程在断点处停下来的时候就处于TASK_TRACED状态。
Z TASK_DEAD - EXIT_ZOMBIE,退出状态,进程成为僵尸进程。进程在退出的过程中,处于TASK_DEAD状态。在这个退出过程中,进程占有的所有资源将被回收,除了task_struct结构(以及少数资源)以外。于是进程就只剩下task_struct这么个空壳,故称为僵尸。
X TASK_DEAD - EXIT_DEAD,退出状态,进程即将被销毁。进程在退出过程中也可能不会保留它的task_struct。此时,进程将被置于EXIT_DEAD退出状态,这意味着接下来的代码立即就会将该进程彻底释放。所以EXIT_DEAD状态是非常短暂的,几乎不可能通过ps命令捕捉到。
  • 进程状态变迁

进程自创建以后,状态可能发生一系列的变化,直到进程退出。而尽管进程状态有好几种,但是进程状态的变迁却只有两个方向——从TASK_RUNNING状态变为非TASK_RUNNING状态、或者从非TASK_RUNNING状态变为TASK_RUNNING状态。也就是说,如果给一个TASK_INTERRUPTIBLE状态的进程发送SIGKILL信号,这个进程将先被唤醒(进入TASK_RUNNING状态),然后再响应SIGKILL信号而退出(变为TASK_DEAD状态)。并不会从TASK_INTERRUPTIBLE状态直接退出。

进程从非TASK_RUNNING状态变为TASK_RUNNING状态,是由别的进程(也可能是中断处理程序)执行唤醒操作来实现的。执行唤醒的进程设置被唤醒进程的状态为TASK_RUNNING,然后将其task_struct结构加入到某个CPU的可执行队列中。于是被唤醒的进程将有机会被调度执行。

而进程从TASK_RUNNING状态变为非TASK_RUNNING状态,则有两种途径:

  1. 响应信号而进入TASK_STOPED状态、或TASK_DEAD状态;
  2. 执行系统调用主动进入TASK_INTERRUPTIBLE状态(如nanosleep系统调用)、或TASK_DEAD状态(如exit系统调用);或由于执行系统调用需要的资源得不到满足,而进入TASK_INTERRUPTIBLE状态或TASK_UNINTERRUPTIBLE状态(如select系统调用)。
    显然,这两种情况都只能发生在进程正在CPU上执行的情况下。

Schedstat

含义上面有大致介绍,详细内容见参考内容3.这个部分的内容在发生SWT时可以用到,SWT时两次trace的schedstat部分应该是一样的。
kill的一些用法

参考:

  1. 高通文档:Android Screen Freeze And Watchdog Issues Analysis
  2. Linux进程状态解析 之 R、S、D、T、Z、X
  3. linux调度器(十)——调度器/proc信息解读

Powered by Hexo and Hexo-theme-hiker

Copyright © 2018 - 2022 得一 All Rights Reserved.

访客数 : | 访问量 :