latencytap.stp学习

        如何知道系统延迟的主要原因,是因为磁盘操作,网络原因还是锁竞争?latencytop可以比较清楚指示延迟的原因。systemtap也有个脚本latencytap.stp,具体分析一下他的具体实现,学习一下原理。

        主要就是从任务切换时候,找出处于睡眠状态的任务,从堆栈中找出对应的函数,再根据预设好的优先级往上追溯延迟原因。还是挺巧妙的。

#!/usr/bin/stap

#

# Copyright (C) 2010 Red Hat, Inc.

# Written by William Cohen <wcohen@redhat.com>

#

# This script records the time that a process has spent asleep and attempt

# to provide a reason for that that sleep. The script needs to be run with the

# '--all-modules' option to map the backtrace addresses to function names

# and the function names back to reasons.

#

# stap --all-modules latencytap.stp

 

global priority, reason;

global traced_pid, sleep_time, dequeue;

global this_sleep;

global debug = 0;

 

function log_event:long (p:long)

{

  return (!traced_pid || traced_pid == task_pid(p))  ---从task_struct指针找到它对应的pid

}

 

#func names from hex addresses

function func_backtrace:string (ips:string)

{

  ret = "";

  for (ip=tokenize(ips, " "); ip!=""; ip=tokenize("", " ")) -----tokenize为字符串分隔函数,第二个参数为分隔符

     ret = ret . symname(strtol(ip,16)) . " ";   ------.为连接符号,将字符串连接在一起

  return ret;

}

 

# pick out a reason based on the backtrace function names

function translate:string (bt:string)  ----从堆栈中找到函数符号名

{

  ip=tokenize(bt, " ");

  func = symname(strtol(ip,16))

  pri = 1; rea="";

  while (ip!="") {

    p = priority[func]

    if (p >= pri) {    ---------优先级主要用于归类,比如说网络应该优于文件读取,因为vfs.read可能包括网络读取

      pri = priority[func];

      rea = reason[func];

    }

    ip=tokenize("", " ")   ---------第一个参数分空,在原来的字符串剩余部分继续匹配

    func = symname(strtol(ip,16))

  }

  return rea;

}

 

probe kernel.trace("deactivate_task") !, -----此处!号表示这个trace满足的话,后面的probe就不再使用

      kernel.function("deactivate_task") {  

  s = task_state($p)

  # check to see if task is in appropriate state:

  # TASK_INTERRUPTIBLE      1

  # TASK_UNINTERRUPTIBLE    2

  if (log_event($p) && (s & 3)) { ------判断是否进入睡眠状态

    dequeue[$p] = gettimeofday_us();

  }

}

 

probe kernel.trace("activate_task") !,

      kernel.function("activate_task") {

  if (!log_event($p)) next

 

  a = gettimeofday_us()

  d = dequeue[$p]

  delete dequeue[$p]

  if (d) {

    sleep = a - d

    if (sleep > 0) {

       this_sleep[$p] = sleep      -----记录从休眠到唤醒的时间差 ,修改为this_sleep[task_pid($p)]

#      sleep_time[task_backtrace($p)] <<< sleep --有些系统这个函数不能用

    }

  }

}

 

#FIXME: It would be nicer to get backtrace information in activate_task probe.

# This would eliminate the overhead of probing every context switch

# and this_sleep associate array. However, this needs a properly working

# task_backtrace() to eliminate this probe.

probe scheduler.cpu_on {   ------用户开始在cpu上运行

   p = task_current()   -----此处的p 和上面activate_task中的$p显示不是同一个值,但task_pid(p)和task_pid($p)是同一个,修改为this_sleep[task_pid(p)]

   t = this_sleep[p] 

   if (t){

     delete this_sleep[p]  ------修改为this_sleep[task_pid(p)]

     sleep_time[backtrace()] <<< t

   }

}

 

global sort_latencies;

 

function global_report_latencies() {

  total = 0

 

  foreach ([backtrace] in sleep_time) {

    val = @sum(sleep_time[backtrace]);

    sort_latencies[backtrace] = val;

    total += val;

  }

 

  ansi_clear_screen();

  printf("%-32s %12s %12s %12s %7s%%\n",

    "Reason", "Count", "Average(us)", "Maximum(us)", "Percent");

  foreach ([backtrace] in sort_latencies- limit 20) {

    #print reason count average max percentage

    cause = translate (backtrace);

    # if can't find reason print out a backtrace

    if (cause == "" && debug)

      printf("%s\n", func_backtrace(backtrace));

    printf("%-32s ", cause);

    p = (@sum(sleep_time[backtrace])*100)/total;

    printf("%12d %12d %12d %7d%%\n",

      @count(sleep_time[backtrace]),

           @avg(sleep_time[backtrace]),

           @max(sleep_time[backtrace]),

  p);

  }

  delete sort_latencies;

}

 

probe timer.s(30) {

  global_report_latencies()

  delete sleep_time

}

 

probe begin {

  traced_pid = target()

}

 

# Set up the translations and priorities for each function.

# The vast majority of translations were mechanically generated from the

# latencytop (http://www.latencytop.org/) translation file:

# /usr/share/latencytop/latencytop.trans .

probe begin {

  priority["vfs_read"] = 1;

  reason["vfs_read"] = "Reading from file";

 

  priority["vfs_write"] = 1;

  reason["vfs_write"] = "Writing to file";

 

  priority["__mark_inode_dirty"] = 1;

  reason["__mark_inode_dirty"] = "Marking inode dirty";

 

  priority["vfs_readdir"] = 1;

  reason["vfs_readdir"] = "Reading directory content";

 

  priority["vfs_unlink"] = 1;

  reason["vfs_unlink"] = "Unlinking file";

 

  priority["blocking_notifier_call_chain"] = 1;

  reason["blocking_notifier_call_chain"] = "Blocking notifier";

 

  priority["lock_super"] = 1;

  reason["lock_super"] = "Superblock lock contention";

 

  priority["bdi_sync_supers"] = 1;

  reason["bdi_sync_supers"] = "Sync superblock";

 

  priority["vfs_create"] = 1;

  reason["vfs_create"] = "Creating a file";

 

  priority["__bread"] = 2;

  reason["__bread"] = "Synchronous buffer read";

 

  priority["do_generic_mapping_read"] = 2;

  reason["do_generic_mapping_read"] = "Reading file data";

 

  priority["sock_sendmsg"] = 2;

  reason["sock_sendmsg"] = "Sending data over socket";

 

  priority["do_sys_open"] = 2;

  reason["do_sys_open"] = "Opening file";

 

  priority["do_sys_poll"] = 2;

  reason["do_sys_poll"] = "Waiting for event (poll)";

 

  priority["core_sys_select"] = 2;

  reason["core_sys_select"] = "Waiting for event (select)";

 

  priority["proc_reg_read"] = 2;

  reason["proc_reg_read"] = "Reading from /proc file";

 

  priority["__pollwait"] = 2;

  reason["__pollwait"] = "Waiting for event (poll)";

 

  priority["sys_fcntl"] = 2;

  reason["sys_fcntl"] = "FCNTL system call";

 

  priority["scsi_error_handler"] = 2;

  reason["scsi_error_handler"] = "SCSI error handler";

 

  priority["proc_root_readdir"] = 2;

  reason["proc_root_readdir"] = "Reading /proc directory";

 

  priority["ksoftirqd"] = 2;

  reason["ksoftirqd"] = "Waking ksoftirqd";

 

  priority["run_ksoftirqd"] = 2;

  reason["run_ksoftirqd"] = "Waking ksoftirqd";

 

  priority["migration_thread"] = 2;

  reason["migration_thread"] = "migration() kernel thread";

 

  priority["do_unlinkat"] = 2;

  reason["do_unlinkat"] = "Unlinking file";

 

  priority["__wait_on_buffer"] = 2;

  reason["__wait_on_buffer"] = "Waiting for buffer IO to complete";

 

  priority["pdflush"] = 2;

  reason["pdflush"] = "pdflush() kernel thread";

 

  priority["kjournald"] = 2;

  reason["kjournald"] = "kjournald() kernel thread";

 

  priority["kjournald2"] = 2;

  reason["kjournald2"] = "jdb2() kernel thread";

 

  priority["bdi_writeback_task"] = 2;

  reason["bdi_writeback_task"] = "Flush data to backing device";

 

  priority["bdi_writeback_thread"] = 2;

  reason["bdi_writeback_thread"] = "Flush data to backing dev";

 

  priority["bdi_forker_task"] = 2;

  reason["bdi_forker_task"] = "bdi-* kernel thread";

 

  priority["dm_wait_for_completion"] = 2;

  reason["dm_wait_for_completion"] = "Waiting for device mapper ops";

 

  priority["blkdev_ioctl"] = 2;

  reason["blkdev_ioctl"] = "block device IOCTL";

 

  priority["kauditd_thread"] = 2;

  reason["kauditd_thread"] = "kernel audit daemon";

 

  priority["tty_ioctl"] = 2;

  reason["tty_ioctl"] = "TTY IOCTL";

 

  priority["do_sync_write"] = 2;

  reason["do_sync_write"] = "synchronous write";

 

  priority["kthreadd"] = 2;

  reason["kthreadd"] = "kthreadd kernel thread";

 

  priority["usb_port_resume"] = 2;

  reason["usb_port_resume"] = "Waking up USB device";

 

  priority["usb_autoresume_device"] = 2;

  reason["usb_autoresume_device"] = "Waking up USB device";

 

  priority["khugepaged"] = 2;

  reason["khugepaged"] = "khugepaged() kernel thread";

 

  priority["kswapd"] = 2;

  reason["kswapd"] = "kswapd() kernel thread";

 

  priority["md_thread"] = 2;

  reason["md_thread"] = "Raid resync kernel thread";

 

  priority["i915_wait_request"] = 2;

  reason["i915_wait_request"] = "Waiting for GPU command to complete";

 

  priority["request_module"] = 2;

  reason["request_module"] = "Loading a kernel module";

 

  priority["tty_wait_until_sent"] = 3;

  reason["tty_wait_until_sent"] = "Waiting for TTY to finish sending";

 

  priority["pipe_read"] = 3;

  reason["pipe_read"] = "Reading from a pipe";

 

  priority["pipe_write"] = 3;

  reason["pipe_write"] = "Writing to a pipe";

 

  priority["pipe_wait"] = 3;

  reason["pipe_wait"] = "Waiting for pipe data";

 

  priority["read_block_bitmap"] = 3;

  reason["read_block_bitmap"] = "Reading EXT3 block bitmaps";

 

  priority["scsi_execute_req"] = 3;

  reason["scsi_execute_req"] = "Executing raw SCSI command";

 

  priority["sys_wait4"] = 3;

  reason["sys_wait4"] = "Waiting for a process to die";

 

  priority["sr_media_change"] = 3;

  reason["sr_media_change"] = "Checking for media change";

 

  priority["sr_do_ioctl"] = 3;

  reason["sr_do_ioctl"] = "SCSI cdrom ioctl";

 

  priority["sd_ioctl"] = 3;

  reason["sd_ioctl"] = "SCSI disk ioctl";

 

  priority["sr_cd_check"] = 3;

  reason["sr_cd_check"] = "Checking CDROM media present";

 

  priority["ext3_read_inode"] = 3;

  reason["ext3_read_inode"] = "Reading EXT3 inode";

 

  priority["htree_dirblock_to_tree"] = 3;

  reason["htree_dirblock_to_tree"] = "Reading EXT3 directory htree";

 

  priority["ext3_readdir"] = 3;

  reason["ext3_readdir"] = "Reading EXT3 directory";

 

  priority["ext3_bread"] = 3;

  reason["ext3_bread"] = "Synchronous EXT3 read";

 

  priority["ext3_free_branches"] = 3;

  reason["ext3_free_branches"] = "Unlinking file on EXT3";

 

  priority["ext3_get_branch"] = 3;

  reason["ext3_get_branch"] = "Reading EXT3 indirect blocks";

 

  priority["ext3_find_entry"] = 3;

  reason["ext3_find_entry"] = "EXT3: Looking for file";

 

  priority["__ext3_get_inode_loc"] = 3;

  reason["__ext3_get_inode_loc"] = "Reading EXT3 inode";

 

  priority["ext3_delete_inode"] = 3;

  reason["ext3_delete_inode"] = "EXT3 deleting inode";

 

  priority["sync_page"] = 3;

  reason["sync_page"] = "Writing a page to disk";

 

  priority["tty_poll"] = 3;

  reason["tty_poll"] = "Waiting for TTY data";

 

  priority["tty_read"] = 3;

  reason["tty_read"] = "Waiting for TTY input";

 

  priority["tty_write"] = 3;

  reason["tty_write"] = "Writing data to TTY";

 

  priority["update_atime"] = 3;

  reason["update_atime"] = "Updating inode atime";

 

  priority["page_cache_sync_readahead"] = 3;

  reason["page_cache_sync_readahead"] = "Pagecache sync readahead";

 

  priority["do_fork"] = 3;

  reason["do_fork"] = "Fork() system call";

 

  priority["sys_mkdirat"] = 3;

  reason["sys_mkdirat"] = "Creating directory";

 

  priority["lookup_create"] = 3;

  reason["lookup_create"] = "Creating file";

 

  priority["inet_sendmsg"] = 3;

  reason["inet_sendmsg"] = "Sending TCP/IP data";

 

  priority["tcp_recvmsg"] = 3;

  reason["tcp_recvmsg"] = "Receiving TCP/IP data";

 

  priority["link_path_walk"] = 3;

  reason["link_path_walk"] = "Following symlink";

 

  priority["path_walk"] = 3;

  reason["path_walk"] = "Walking directory tree";

 

  priority["sys_getdents"] = 3;

  reason["sys_getdents"] = "Reading directory content";

 

  priority["unix_stream_recvmsg"] = 3;

  reason["unix_stream_recvmsg"] = "Waiting for data on unix socket";

 

  priority["ext3_mkdir"] = 3;

  reason["ext3_mkdir"] = "EXT3: Creating a directory";

 

  priority["journal_get_write_access"] = 3;

  reason["journal_get_write_access"] = "EXT3: Waiting for journal access";

 

  priority["synchronize_rcu"] = 3;

  reason["synchronize_rcu"] = "Waiting for RCU";

 

  priority["input_close_device"] = 3;

  reason["input_close_device"] = "Closing input device";

 

  priority["mousedev_close_device"] = 3;

  reason["mousedev_close_device"] = "Closing mouse device";

 

  priority["mousedev_release"] = 3;

  reason["mousedev_release"] = "Closing mouse device";

 

  priority["mousedev_open"] = 3;

  reason["mousedev_open"] = "Opening mouse device";

 

  priority["kmsg_read"] = 3;

  reason["kmsg_read"] = "Reading from dmesg";

 

  priority["sys_futex"] = 3;

  reason["sys_futex"] = "Userspace lock contention";

 

  priority["do_futex"] = 3;

  reason["do_futex"] = "Userspace lock contention";

 

  priority["vt_waitactive"] = 3;

  reason["vt_waitactive"] = "vt_waitactive IOCTL";

 

  priority["acquire_console_sem"] = 3;

  reason["acquire_console_sem"] = "Waiting for console access";

 

  priority["filp_close"] = 3;

  reason["filp_close"] = "Closing a file";

 

  priority["sync_inode"] = 3;

  reason["sync_inode"] = "(f)syncing an inode to disk";

 

  priority["ata_exec_internal_sg"] = 3;

  reason["ata_exec_internal_sg"] = "Executing internal ATA command";

 

  priority["writeback_inodes"] = 3;

  reason["writeback_inodes"] = "Writing back inodes";

 

  priority["ext3_orphan_add "] = 3;

  reason["ext3_orphan_add "] = "EXT3 adding orphan";

 

  priority["ext3_mark_inode_dirty "] = 3;

  reason["ext3_mark_inode_dirty "] = "EXT3 marking inode dirty";

 

  priority["ext3_unlink "] = 3;

  reason["ext3_unlink "] = "EXT3 unlinking file";

 

  priority["ext3_create"] = 3;

  reason["ext3_create"] = "EXT3 Creating a file";

 

  priority["log_do_checkpoint"] = 3;

  reason["log_do_checkpoint"] = "EXT3 journal checkpoint";

 

  priority["generic_delete_inode"] = 3;

  reason["generic_delete_inode"] = "Deleting an inode";

 

  priority["proc_delete_inode"] = 3;

  reason["proc_delete_inode"] = "Removing /proc file";

 

  priority["do_truncate"] = 3;

  reason["do_truncate"] = "Truncating file";

 

  priority["sys_execve"] = 3;

  reason["sys_execve"] = "Executing a program";

 

  priority["journal_commit_transaction"] = 3;

  reason["journal_commit_transaction"] = "EXT3: committing transaction";

 

  priority["__stop_machine_run"] = 3;

  reason["__stop_machine_run"] = "Freezing the kernel (for module load)";

 

  priority["sys_munmap"] = 3;

  reason["sys_munmap"] = "unmapping memory";

 

  priority["sys_mmap"] = 3;

  reason["sys_mmap"] = "mmaping memory";

 

  priority["sync_buffer"] = 3;

  reason["sync_buffer"] = "Writing buffer to disk (synchronous)";

 

  priority["inotify_inode_queue_event"] = 3;

  reason["inotify_inode_queue_event"] = "Inotify event";

 

  priority["proc_lookup"] = 3;

  reason["proc_lookup"] = "Looking up /proc file";

 

  priority["generic_make_request"] = 3;

  reason["generic_make_request"] = "Creating block layer request";

 

  priority["get_request_wait"] = 3;

  reason["get_request_wait"] = "Creating block layer request";

 

  priority["alloc_page_vma"] = 3;

  reason["alloc_page_vma"] = "Allocating a VMA";

 

  priority["blkdev_direct_IO"] = 3;

  reason["blkdev_direct_IO"] = "Direct block device IO";

 

  priority["sys_mprotect"] = 3;

  reason["sys_mprotect"] = "mprotect() system call";

 

  priority["shrink_icache_memory"] = 3;

  reason["shrink_icache_memory"] = "reducing inode cache memory footprint";

 

  priority["vfs_stat_fd"] = 3;

  reason["vfs_stat_fd"] = "stat() operation";

 

  priority["cdrom_open"] = 3;

  reason["cdrom_open"] = "opening cdrom device";

 

  priority["sys_epoll_wait"] = 3;

  reason["sys_epoll_wait"] = "Waiting for event (epoll)";

 

  priority["sync_sb_inodes"] = 3;

  reason["sync_sb_inodes"] = "Syncing inodes";

 

  priority["tcp_connect"] = 3;

  reason["tcp_connect"] = "TCP/IP connect";

 

  priority["ata_scsi_ioctl"] = 3;

  reason["ata_scsi_ioctl"] = "ATA/SCSI disk ioctl";

 

  priority["kvm_vcpu_ioctl"] = 3;

  reason["kvm_vcpu_ioctl"] = "KVM ioctl";

 

  priority["do_rmdir"] = 3;

  reason["do_rmdir"] = "Removing directory";

 

  priority["vfs_rmdir"] = 3;

  reason["vfs_rmdir"] = "Removing directory";

 

  priority["sys_flock"] = 3;

  reason["sys_flock"] = "flock() on a file";

 

  priority["usbdev_open"] = 3;

  reason["usbdev_open"] = "opening USB device";

 

  priority["lock_kernel"] = 3;

  reason["lock_kernel"] = "Big Kernel Lock contention";

 

  priority["blk_execute_rq"] = 3;

  reason["blk_execute_rq"] = "Submitting block IO";

 

  priority["scsi_cmd_ioctl"] = 3;

  reason["scsi_cmd_ioctl"] = "SCSI ioctl command";

 

  priority["acpi_ec_transaction"] = 3;

  reason["acpi_ec_transaction"] = "ACPI hardware access";

 

  priority["journal_get_undo_access"] = 3;

  reason["journal_get_undo_access"] = "Waiting for EXT3 journal undo operation";

 

  priority["i915_irq_wait"] = 3;

  reason["i915_irq_wait"] = "Waiting for GPU interrupt";

 

  priority["i915_gem_throttle_ioctl"] = 3;

  reason["i915_gem_throttle_ioctl"] = "Throttling GPU while waiting for commands";

 

  priority["do_page_fault"] = 5;

  reason["do_page_fault"] = "Page fault";

 

  priority["handle_mm_fault"] = 5;

  reason["handle_mm_fault"] = "Page fault";

 

  priority["filemap_fault"] = 5;

  reason["filemap_fault"] = "Page fault";

 

  priority["sync_filesystems"] = 5;

  reason["sync_filesystems"] = "Syncing filesystem";

 

  priority["sys_nanosleep"] = 5;

  reason["sys_nanosleep"] = "Application requested delay";

 

  priority["sys_pause"] = 5;

  reason["sys_pause"] = "Application requested delay";

 

  priority["evdev_read"] = 5;

  reason["evdev_read"] = "Reading keyboard/mouse input";

 

  priority["do_fsync"] = 5;

  reason["do_fsync"] = "fsync() on a file";

 

  priority["__log_wait_for_space"] = 5;

  reason["__log_wait_for_space"] = "Waiting for EXT3 journal space";

 

}

 

<think>好的,用户想了解.stp文件的相关信息,包括定义和处理方法。首先,我需要整理现有引用内容,确保回答准确。引用1提到STP文件阅读器,可以查看和操作三维模型;引用2比较了IGS和STP的区别,指出STP存储参数化数据,适合精确建模;引用3和4涉及使用OpenCASCADE处理STP文件,包括保存点云和导入。 用户可能想知道STP文件的基本概念、应用场景以及处理工具。需要分点回答,结构清晰。根据引用1,STP是STEP标准的3D模型文件,用于CAD数据交换,应用在工程和制造领域。处理工具方面,可以推荐引用1中的阅读器,还有CAD软件如SolidWorks,以及编程库如OpenCASCADE。 另外,用户可能对处理步骤感兴趣,比如如何打开、编辑或转换STP文件。需要结合引用3和4中的代码示例,说明使用OpenCASCADE导入和保存的方法。同时,要提到不同工具的选择依据,如工程师常用专业软件,开发者可能用开源库。 还需注意引用格式,在相关部分添加脚注。比如在解释STP应用时引用1和2,处理工具部分引用1、3、4。最后,生成相关问题时要覆盖文件格式比较、工具推荐、转换方法等,确保问题有针对性,帮助用户深入理解。</think>### 关于 .stp 文件及其处理方法的说明 #### 1. **.stp 文件的定义与用途** - **文件格式**:`.stp` 文件是 **STEP(Standard for the Exchange of Product Data)** 标准的文件格式,用于存储三维模型数据,支持参数化设计和精确几何描述[^1][^2]。 - **应用场景**:广泛应用于机械设计、工业制造、CAD 数据交换等领域,支持复杂装配体、材料属性等信息的存储[^1]。 #### 2. **如何查看 .stp 文件** - **专用工具**:推荐使用轻量级工具如 **STP 文件阅读器**(支持模型旋转、缩放、透视),或专业软件如 **SolidWorks**、**AutoCAD**、**FreeCAD**。 - **编程处理**:开发者可通过开源库(如 **OpenCASCADE**)解析和生成 `.stp` 文件,例如导入点云数据或保存三维模型[^3][^4]。 #### 3. **处理 .stp 文件的技术方法** - **代码示例**(基于 OpenCASCADE): ```cpp // 导入 .stp 文件 STEPControl_Reader reader; IFSelect_ReturnStatus status = reader.ReadFile("model.stp"); if (status == IFSelect_RetDone) { reader.TransferRoots(); TopoDS_Shape shape = reader.OneShape(); } // 导出为 .stp 文件 STEPControl_Writer writer; writer.Transfer(shape, STEPControl_AsIs); writer.Write("output.stp"); ``` 此代码展示了基础导入导出操作,需根据实际需求调整几何处理逻辑。 #### 4. **与其他格式的对比** - **与 .igs 的区别**:`.igs`(IGES)文件侧重于表面几何,而 `.stp` 支持参数化设计和更丰富的元数据,适合高精度工程需求。 - **与 .stl 的区别**:`.stl` 仅描述三角网格表面,适用于 3D 打印;`.stp` 包含拓扑结构和设计参数,适合制造与装配。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值