Linux New System Call: process_vm_readv & process_vm_writev

    在Linux kernel 3.2 merge window中已添加两个新的系统调用:process_vm_readv process_vm_writev

    这两个新的系统调用用于从目标进程中指定地址读取内存到当前进程,同时支持readv和writev,现在它们只用于openMPI快速进程通信,不过可以知道此系统调用可以改进很多现有的进程通信的性能。

 

    在kernel中已存在多种进程通讯的方式,如pipe, unix socket, fifo, shm, msgqueue...,在一些注重性能的场合(如快速进程间数据共享)下share memory则用的较多,这些进程通信都无法实现从目标进程读取内存(shm需要开辟共享内存,不是严格的自己本身的进程内存),当然要实现随意读取其他进程内存也是很容易实现的,在kernel中有以下几种方法:

 

  • /proc/pid/mem:这是进程内存的文件表示形式,如果能有权限读取此文件,则可访问进程中任意的内存数据,同时也可以修改。问题是你得首先拿到读取mem文件的权限,就连root权限都不行,还得ptrace,就是说只有ptrace上目标进程的进程才能读取该文件。至于为什么需要这样的限制呢?很遗憾,原因已经丢失,估计当时提交patch的人没写好commit description,所以commit patch时一定要写好description,不然n年后谁能看懂你的代码,据猜测是因为安全方面的考虑。
  • unix socket SCM_RIGHTS: SCM_RIGHTS的作用就是一个进程把已open的fd通过unix socket发送到目标进程,这样就实现了数据共享,这种方案的问题是不具有扩展性,如果n个进程相互之间都需要共享数据的话,去不是fight fd横飞。

 

    用gdb attach目标进程时可以随意读写目标进程的内存,process_vm_readv和process_vm_writev的实现同样也是借助于ptrace_access的实现。

 

   有了process_vm_readv和process_vm_writev之后,以后写debug程序就方便的多了,再也不需要搬上ptrace,对于一些不能中断的online程序调试是个很不错的feature(当然可能会破坏进程内存一致性的问题),最简单的应用就是读取程序的全局变量(首先须得到global变量的地址)。---这个问题本人以前苦思的很久,如何在不间断程序运行的前提下读取进程内存以实现快速问题定位?ptrace当然可以实现,不多ptrace的设计是一定要interrupt程序运行的;或者向进程发送信号,在程序的信号处理程序中打印所需的进程变量,这样的问题是需要编程人员写debug code,不是太简便;又或者加个轻量级的telnet server在进程中,调试时telnet到进程的端口,输入command,打印变量,这样的解决方案比较正式,可用于复杂的project中,但仍然比较重量级。综合而言, process_vm_readv和process_vm_writev提供了一种极为简便的读取进程内存的方法,值得关注!

 

 

 

 

你可能感兴趣的:(linux,kernel,进程通信,系统调用)