诊断调试命令strace用法

2023-05-16

strace是什么?

按照strace官网的描述, strace是一个可用于诊断、调试和教学的Linux用户空间跟踪器。我们用它来监控用户空间进程和内核的交互,比如系统调用、信号传递、进程状态变更等。

strace底层使用内核的ptrace特性来实现其功能。

在运维的日常工作中,故障处理和问题诊断是个主要的内容,也是必备的技能。strace作为一种动态跟踪工具,能够帮助运维高效地定位进程和服务故障。它像是一个侦探,通过系统调用的蛛丝马迹,告诉你异常的真相。

strace能做什么?

运维工程师都是实践派的人,我们还是先来个例子吧。

我们从别的机器copy了个叫做some_server的软件包过来,开发说直接启动就行,啥都不用改。可是尝试启动时却报错,根本起不来!

启动命令:

./some_server ../conf/some_server.conf

输出:

FATAL: InitLogFile failed iRet: -1!
Init error: -1655

为什么起不来呢?从日志看,似乎是初始化日志文件失败,真相到底怎样呢?我们用strace来看看。

strace -tt -f  ./some_server ../conf/some_server.conf

输出:

 

我们注意到,在输出InitLogFile failed错误的前一行,有个open系统调用:

23:14:24.448034 open("/usr/local/apps/some_server/log//server_agent.log", O_RDWR|O_CREAT|O_APPEND|O_LARGEFILE, 0666) = -1 ENOENT (No such file or directory)

它尝试打开文件/usr/local/apps/some_server/log//server_agent.log来写(不存在则创建),可是却出错了,返回码是-1, 系统错误号errorno为ENOENT。 查下open系统调用的手册页:

man 2 open

搜索ENOENT这个错误号errno的解释

ENOENT O_CREAT  is not set and the named file does not exist.  Or, a directory component in pathname does not exist or is a dangling symbolic link.

这里说得比较清楚,因为我们例子中的open选项指定了O_CREAT选项,这里errno为ENOENT的原因是日志路径中某个部分不存在或者是一个失效的符号链接。我们来一级一级看下路径中的哪部分不存在:

ls -l /usr/local/apps/some_server/log
ls: cannot access /usr/local/apps/some_server/log: No such file or directory
ls -l /usr/local/apps/some_server
total 8
drwxr-xr-x 2 root users 4096 May 14 23:13 bin
drwxr-xr-x 2 root users 4096 May 14 22:48 conf

原来是log子目录不存在!上层目录都是存在的。手工创建log子目录后,服务就能正常启动了。

回过头来, strace究竟能做什么呢?

它能够打开应用进程的这个黑盒,通过系统调用的线索,告诉你进程大概在干嘛。

strace怎么用?

既然strace是用来跟踪用户空间进程的系统调用和信号的,在进入strace使用的主题之前,我们的先理解什么是系统调用。

关于系统调用:

按维基百科中的解释,在计算机中,系统调用(英语:system call),又称为系统呼叫,指运行在用户空间的程序向操作系统内核请求需要更高权限运行的服务。

系统调用提供用户程序与操作系统之间的接口。操作系统的进程空间分为用户空间和内核空间:

  • 操作系统内核直接运行在硬件上,提供设备管理、内存管理、任务调度等功能。

  • 用户空间通过API请求内核空间的服务来完成其功能——内核提供给用户空间的这些API, 就是系统调用。

在Linux系统上,应用代码通过glibc库封装的函数,间接使用系统调用。

Linux内核目前有300多个系统调用,详细的列表可以通过syscalls手册页查看。这些系统调用主要分为几类:

文件和设备访问类 比如open/close/read/write/chmod等
进程管理类 fork/clone/execve/exit/getpid等
信号类 signal/sigaction/kill 等
内存管理 brk/mmap/mlock等
进程间通信IPC shmget/semget * 信号量,共享内存,消息队列等
网络通信 socket/connect/sendto/sendmsg 等
其他

熟悉Linux系统调用/系统编程,能够让我们在使用strace时得心应手。不过,对于运维的问题定位来说,知道strace这个工具,会查系统调用手册,就差不多够了。

想要深入了解的同学,建议阅读《Linux系统编程》, 《Unix环境高级编程》等书籍。

我们回到strace的使用上来。strace有两种运行模式。

一种是通过它启动要跟踪的进程。用法很简单,在原本的命令前加上strace即可。比如我们要跟踪 "ls -lh /var/log/messages" 这个命令的执行,可以这样:

strace ls -lh /var/log/messages

另外一种运行模式,是跟踪已经在运行的进程,在不中断进程执行的情况下,理解它在干嘛。 这种情况,给strace传递个-p pid 选项即可。

比如,有个在运行的some_server服务,第一步,查看pid:

pidof some_server                      
17553

得到其pid 17553然后就可以用strace跟踪其执行:

strace -p 17553

完成跟踪时,按ctrl + C 结束strace即可。

strace有一些选项可以调整其行为,我们这里介绍下其中几个比较常用的,然后通过示例讲解其实际应用效果。

strace常用选项:

从一个示例命令来看:

strace -tt -T -v -f -e trace=file -o /data/log/strace.log -s 1024 -p 23489

-tt 在每行输出的前面,显示毫秒级别的时间
-T 显示每次系统调用所花费的时间
-v 对于某些相关调用,把完整的环境变量,文件stat结构等打出来。
-f 跟踪目标进程,以及目标进程创建的所有子进程
-e 控制要跟踪的事件和跟踪行为,比如指定要跟踪的系统调用名称
-o 把strace的输出单独写到指定的文件
-s 当系统调用的某个参数是字符串时,最多输出指定长度的内容,默认是32个字节
-p 指定要跟踪的进程pid, 要同时跟踪多个pid, 重复多次-p选项即可。

实例:跟踪nginx, 看其启动时都访问了哪些文件

strace -tt -T -f -e trace=file -o /data/log/strace.log -s 1024 ./nginx

部分输出:

 

输出中,第一列显示的是进程的pid, 接着是毫秒级别的时间,这个是-tt 选项的效果。

每一行的最后一列,显示了该调用所花的时间,是-T选项的结果。

这里的输出只显示和文件访问有关的内容,这是因为我们通过-e trace=file 选项指定了。

strace问题定位案例

1、定位进程异常退出

问题:机器上有个叫做run.sh的常驻脚本,运行一分钟后会死掉。需要查出死因。

定位:进程还在运行时,通过ps命令获取其pid, 假设我们得到的pid是24298

strace -o strace.log -tt -p 24298

查看strace.log, 我们在最后2行看到如下内容:

22:47:42.803937 wait4(-1,  <unfinished ...>
22:47:43.228422 +++ killed by SIGKILL +++

这里可以看出,进程是被其他进程用KILL信号杀死的。

实际上,通过分析,我们发现机器上别的服务有个监控脚本,它监控一个也叫做run.sh的进程,当发现run.sh进程数大于2时,就会把它杀死重启。结果导致我们这个run.sh脚本被误杀。

进程被杀退出时,strace会输出killed by SIGX(SIGX代表发送给进程的信号)等,那么,进程自己退出时会输出什么呢?

这里有个叫做test_exit的程序,其代码如下:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv) {
       exit(1);
}

我们strace看下它退出时strace上能看到什么痕迹。

strace -tt -e trace=process -f ./test_exit

说明: -e trace=process 表示只跟踪和进程管理相关的系统调用。

输出:

23:07:24.672849 execve("./test_exit", ["./test_exit"], [/* 35 vars */]) = 0
23:07:24.674665 arch_prctl(ARCH_SET_FS, 0x7f1c0eca7740) = 0
23:07:24.675108 exit_group(1)           = ?
23:07:24.675259 +++ exited with 1 +++

可以看出,进程自己退出时(调用exit函数,或者从main函数返回), 最终调用的是exit_group系统调用, 并且strace会输出exited with X(X为退出码)。

可能有人会疑惑,代码里面明明调用的是exit, 怎么显示为exit_group?

这是因为这里的exit函数不是系统调用,而是glibc库提供的一个函数,exit函数的调用最终会转化为exit_group系统调用,它会退出当前进程的所有线程。实际上,有一个叫做_exit()的系统调用(注意exit前面的下划线), 线程退出时最终会调用它。

2、定位共享内存异常

有个服务启动时报错:

shmget 267264 30097568: Invalid argument
Can not get shm...exit!

错误日志大概告诉我们是获取共享内存出错,通过strace看下:

strace -tt -f -e trace=ipc ./a_mon_svr     ../conf/a_mon_svr.conf

输出:

22:46:36.351798 shmget(0x5feb, 12000, 0666) = 0
22:46:36.351939 shmat(0, 0, 0)          = ?
Process 21406 attached
22:46:36.355439 shmget(0x41400, 30097568, 0666) = -1 EINVAL (Invalid argument)
shmget 267264 30097568: Invalid argument
Can not get shm...exit!

这里,我们通过-e trace=ipc 选项,让strace只跟踪和进程通信相关的系统调用。

从strace输出,我们知道是shmget系统调用出错了,errno是EINVAL。同样, 查询下shmget手册页,搜索EINVAL的错误码的说明:

EINVAL A new segment was to be created and size < SHMMIN or size > SHMMAX, or no new segment was to be created, a segment with given key existed, but size is greater than the size of that segment

翻译下,shmget设置EINVAL错误码的原因为下列之一:

  • 要创建的共享内存段比 SHMMIN小 (一般是1个字节)

  • 要创建的共享内存段比 SHMMAX 大 (内核参数kernel.shmmax配置)

  • 指定key的共享内存段已存在,其大小和调用shmget时传递的值不同。

从strace输出看,我们要连的共享内存key 0x41400, 指定的大小是30097568字节,明显与第1、2种情况不匹配。那只剩下第三种情况。使用ipcs看下是否真的是大小不匹配:

ipcs  -m | grep 41400
key        shmid      owner      perms      bytes      nattch     status    
0x00041400 1015822    root       666        30095516   1

可以看到,已经0x41400这个key已经存在,并且其大小为30095516字节,和我们调用参数中的30097568不匹配,于是产生了这个错误。

在我们这个案例里面,导致共享内存大小不一致的原因,是一组程序中,其中一个编译为32位,另外一个编译为64位,代码里面使用了long这个变长int数据类型。

把两个程序都编译为64解决了这个问题。

这里特别说下strace的-e trace选项。

要跟踪某个具体的系统调用,-e trace=xxx即可。但有时候我们要跟踪一类系统调用,比如所有和文件名有关的调用、所有和内存分配有关的调用。

如果人工输入每一个具体的系统调用名称,可能容易遗漏。于是strace提供了几类常用的系统调用组合名字。

-e trace=file     跟踪和文件访问相关的调用(参数中有文件名)
-e trace=process  和进程管理相关的调用,比如fork/exec/exit_group
-e trace=network  和网络通信相关的调用,比如socket/sendto/connect
-e trace=signal    信号发送和处理相关,比如kill/sigaction
-e trace=desc  和文件描述符相关,比如write/read/select/epoll等
-e trace=ipc 进程见同学相关,比如shmget等

绝大多数情况,我们使用上面的组合名字就够了。实在需要跟踪具体的系统调用时,可能需要注意C库实现的差异。

比如我们知道创建进程使用的是fork系统调用,但在glibc里面,fork的调用实际上映射到了更底层的clone系统调用。使用strace时,得指定-e trace=clone, 指定-e trace=fork什么也匹配不上。

3、 性能分析

假如有个需求,统计Linux 4.5.4 版本内核中的代码行数(包含汇编和C代码)。这里提供两个Shell脚本实现:

poor_script.sh:

!/bin/bash

total_line=0
while read filename; do
   line=$(wc -l $filename | awk ‘{print $1}’)
   (( total_line += line ))
done < <( find linux-4.5.4 -type f  ( -iname ‘.c’ -o -iname ‘.h’ -o -iname ‘*.S’ ) )
echo “total line: $total_line”

good_script.sh:

!/bin/bash

find linux-4.5.4 -type f  ( -iname ‘.c’ -o -iname ‘.h’ -o -iname ‘*.S’ ) -print0 \
| wc -l —files0-from - | tail -n 1

两段代码实现的目的是一样的。 我们通过strace的-c选项来分别统计两种版本的系统调用情况和其所花的时间(使用-f同时统计子进程的情况)

从两个输出可以看出,good_script.sh 只需要2秒就可以得到结果:19613114行。它大部分的调用(calls)开销是文件操作(read/open/write/close)等,统计代码行数本来就是干这些事情。

而poor_script.sh完成同样的任务则花了539秒。它大部分的调用开销都在进程和内存管理上(wait4/mmap/getpid…)。

实际上,从两个图中clone系统调用的次数,我们可以看出good_script.sh只需要启动3个进程,而poor_script.sh完成整个任务居然启动了126335个进程!

而进程创建和销毁的代价是相当高的,性能不差才怪。

总结

当发现进程或服务异常时,我们可以通过strace来跟踪其系统调用,“看看它在干啥”,进而找到异常的原因。熟悉常用系统调用,能够更好地理解和使用strace。

当然,万能的strace也不是真正的万能。当目标进程卡死在用户态时,strace就没有输出了。

这个时候我们需要其他的跟踪手段,比如gdb/perf/SystemTap等。

备注:

1、perf原因kernel支持

2、ftrace  kernel支持可编程

3、systemtap 功能强大,RedHat系统支持,对用户态,内核态逻辑都能探查,使用范围更广

本文永久更新链接地址:http://www.linuxidc.com/Linux/2018-01/150654.htm

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

诊断调试命令strace用法 的相关文章

  • 诊断调试命令strace用法

    strace是什么 xff1f 按照strace官网的描述 strace是一个可用于诊断 调试和教学的Linux用户空间跟踪器 我们用它来监控用户空间进程和内核的交互 xff0c 比如系统调用 信号传递 进程状态变更等 strace底层使用
  • linux下strace的用法

    strace多个进程 strace ps aux grep ProcGroupName grep v grep awk print p 2 xargs echo strace多个进程id下的所有线程 strace ps T ProcId1
  • 如何在 Mac OS X 中跟踪程序的系统调用?

    我想跟踪系统调用find命令调试一些性能问题但是我不知道如何在 Mac OS X Yosemite 上执行此操作 如何跟踪任意程序的系统调用 类似于strace在 FreeBSD 上有吗 我对跟踪文件系统相关的调用特别感兴趣 建议接受的答案
  • 在文本文件中打印 strace 命令的输出

    我需要将以下命令的结果写入文本文件 但该命令不起作用并且在使用时cat output txt什么也不给我看 请帮我解决这个问题吗 strace r y e read Program l o output txt thanks 为了将来的参考
  • iPhone:strace、dtruss、dtrace 或同等工具?

    有谁知道是否有类似的东西strace dtruss or dtrace对于iPhone tester iPhone tmp root apt cache search dtruss tester iPhone tmp root apt ca
  • 使用 ptrace 提取系统调用名称和参数

    我正在做一项必须执行的任务strace喜欢使用功能ptrace 到目前为止 我已经找到了如何提取系统调用号和返回值 如下所示 In parent process struct user regs struct regs ptrace PTR
  • 相当于 mac os X 上的 strace -feopen

    这对于调试很有用 因此与编程相关 在linux上 我们可以使用命令 strace feopen python myfile py 找出加载了哪些 python 模块和共享对象 macOS X 上是否有等效的单行代码 我想你的意思是strac
  • 跟踪对共享库的调用

    我正在Linux下开发一个程序 出于调试目的 我想跟踪从程序到某个 最好是共享 库的所有调用 我不想跟踪库内发生的调用 对于系统调用 有 strace 是否有任何工具可以跟踪对共享库的调用 您正在寻找的工具称为ltrace 它允许跟踪从程序
  • 无法从 Linux 连接到 SQL Server

    我正在尝试连接到 CentOS 5 8 上的 SQL Server 2008 我正在使用 unixODBC 2 3 0 和 SQL Server ODBC 驱动程序 www microsoft com en us download deta
  • Strace 检测到对 brk 的调用,但 GDB 不会在断点处停止

    我已经尝试调试内存泄漏相当长一段时间了 我的主要问题是无法使用像 Valgrind 之类的正确工具 所以我选择了普通的 GDB strace 我的程序是一个循环 在每次迭代中 它都会创建一些对象 然后调用它们的析构函数 正如它所解释的her
  • poll 系统调用超时

    附加strace显示了很多这样的消息 poll fd 5 events POLLIN fd 6 events POLLIN fd 7 events POLLIN fd 8 events POLLIN fd 9 events POLLIN f
  • ptrace 在 Linux 中如何工作?

    The ptrace系统调用允许父进程检查附加的子进程 例如 在 Linux 中 strace 这是通过实现ptracesystem call 可以检查子进程调用的系统调用 当附加的子进程调用系统调用时 可以通知 ptracing 父进程
  • Stracing 以附加到多线程进程

    如果我想跟踪一个多线程进程 其所有线程 我应该怎么做 我知道可以执行 strace f 来跟踪分叉进程吗 但是当我开始跟踪时附加到已经是多线程的进程怎么样 有一种方法可以告诉 strace 跟踪属于该进程的所有线程的所有系统调用吗 2021
  • 如何获取 Linux 中进程的进程树跟踪/日志?

    我想知道脚本启动哪些可执行文件以及以什么顺序 并递归地跟踪这些可执行文件 例如 假设我这里有一个 bash 脚本 称为 abc sh bin bash ls gcc 我想使用 trace log 命令 运行此脚本并得到如下内容 abc sh
  • 获取python项目使用的所有模块/包

    我有一个 python GUI 应用程序 现在我需要知道应用程序链接到的所有库 这样我就可以检查所有库的许可证兼容性 我尝试过使用 strace 但 strace 似乎会报告所有包 即使应用程序未使用它们 而且 我尝试了 python Mo
  • 在 strace 中捕获 vDSO

    我想知道是否有一种方法可以捕获 换句话说观察 vDSO 调用 例如gettimeofday in strace 另外 有没有一种方法可以在不加载的情况下执行二进制文件linux vdso so 1 标志或环境变量 最后 如果我编写一个程序来
  • LD_PRELOAD 和 strace 有什么区别?

    这两种方法都用于收集系统调用及其参数和返回值 当我们更愿意LD PRELOAD为什么 也许我们可以说我们只能通过以下方式收集系统调用strace但我们可以收集图书馆的电话LD PRELOAD诡计 然而 还有另一个库的跟踪器 其名称是ltra
  • Linux 上的 wall-time 分析

    我有一个应用程序 我想分析在各种活动中花费了多少时间 由于此应用程序是 I O 密集型 因此我希望获得一份报告 该报告将总结每个库 系统调用所花费的时间 挂起时间 我已经尝试过 oprofile 但它似乎给出了 Unhalted CPU 周
  • 使用 strace 修复挂起内存问题

    我有一个在 RHEL6 x 64 位 上运行的多线程进程 我发现当我尝试启动该进程时 该进程挂起并且大多数线程 同一进程的 崩溃 有些线程等待线程之间的共享内存被创建 我可以看到所有的共享内存都没有被创建 但是当我使用 strace 时 进
  • 真实设备中的 Android strace

    我有以下情况 我想监控Android手机上的系统调用 所以 我编写了一个脚本来做到这一点 使用 Android 模拟器可以完美地工作 将应用程序的痕迹写入我的 Ubuntu 上的特定文件中 问题是当我连接一个真实的手机来分析它时 它在结果文

随机推荐

  • [笔记] 代码整洁之道1:序言

    软件质量 xff0c 不但依赖于架构和管理 xff0c 而且与代码质量紧密相关 神在细节之中 建筑师Ludwig mies van der Role如是说 以小见大 xff0c 做好细节是做好整体的基础 约在1951年 xff0c 名为 全
  • [笔记] 代码整洁之道2:章1整洁代码

    泥潭 烂尾 死掉 糟糕代码的坑自不多言 xff0c 如何评估代码有多糟糕 xff1f 看WTF min 那什么是整洁代码 xff1f 易读 逻辑 干净 漂亮 舒服 学一学 xff08 美国 xff09 童子军军规 xff1a 让营地比你来时
  • [笔记] 代码整洁之道3:章2有意义的命名

    修改命名是一种低成本提升代码可读性的方法 xff0c 怎么起有意义的名呢 xff1f 参考如下方法 xff1a 名副其实 变量 函数或类的名称应该告诉你 xff0c 它为什么会存在 xff0c 它做什么事 xff0c 应该怎么用 如果连名称
  • OpenCV minAreaRect

    OpenCV Minimum Area Rectangle In the previous blog we discussed image moments and how different contour features such as
  • OpenCV错误(-215:Assertion failed) npoints > 0 in function

    在使用OpenCV绘图函数时容易遇到 215 Assertion failed npoints gt 0 错误 代码如下 xff1a import numpy import cv2 mask 61 numpy zeros 4000 4000
  • 【个人成长】两个帮助你认清职场中自己位置的工具

    原文来自吴军老师的 谷歌方法论 第182封信 xff1a 两个帮助你认清自己位置的工具 当你在职场中不顺的时候可以考虑进行下自我位置评估 工具一 xff1a 主客观评价四方表 xff1a 表中的第一列自己填写 第一行填写自己的优点 成绩 贡
  • Ubuntu linux设置从当前目录下加载动态库so文件

    linux的excutable在执行的时候缺省是先搜索 lib和 usr lib这两个目录 xff0c 然后按照ld so conf里面的配置搜索绝对路径 xff0c linux缺省是不会在当前目录搜索动态库的 windows加载动态库的时
  • HTTP Get,Post请求详解

    请求类型 三种最常见的请求类型是 xff1a GET xff0c POST 和 HEAD GET xff1a 获取一个文档 大部分被传输到浏览器的html xff0c images xff0c js xff0c css 都是通过GET方法发
  • pip安装opencv出错:No module named ‘skbuild‘

    问题 xff1a pip安装opencv时出错 xff1a No module named 39 skbuild 39 解决方案一 xff08 测试通过 xff09 xff1a pip install upgrade pip 解决方案二 x
  • geoio ImportError: libpoppler.so.71: cannot open shared object file: No such file or directory

    问题 xff1a 使用conda安装gdal后 xff0c 在回滚变更环境后出错 xff1a geoio ImportError libpoppler so 71 cannot open shared object file No such
  • 开运算、闭运算及其所用

    1 开运算 开运算 61 先腐蚀运算 xff0c 再膨胀运算 xff08 看上去把细微连在一起的两块目标分开了 xff09 开运算的效果图如下图所示 xff1a 开运算总结 xff1a xff08 xff11 xff09 开运算能够除去孤立
  • Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)

    在PyCharm运行Python代码运行时出现错误导致退出 xff1a Process finished with exit code 139 interrupted by signal 11 SIGSEGV 139错误是Linux错误代码
  • 深度学习优化利器:集成、知识蒸馏和自蒸馏

    为什么简单的 集成 便能够提升性能呢 xff1f 本文是对上述问题的解析 xff0c 作者解读了来自微软研究院高级研究员朱泽园博士 xff0c 以及卡内基梅隆大学机器学习系助理教授李远志的最新论文 在深度学习中理解集成 xff0c 知识蒸馏
  • 解决word无法回退及修改内容不保存问题

    如图 xff0c 撤退按钮瞬间会变灰 即便在未变灰前点击回退也不会有实际回退效果 出现这种情况很可能是模板文件出现损坏或有异常 可以通过删除模板文件让word重新自己生成模板文件来解决 操作步骤如下 xff1a step 1 xff1a 打
  • 错误:AttributeError: module ‘keras.backend.tensorflow_backend‘ has no attribute ‘_is_tf_1‘

    使用tensorflow 43 keras时出现错误 xff1a AttributeError module 39 keras backend tensorflow backend 39 has no attribute 39 is tf
  • linux 已放弃(吐核) (core dumped) 问题分析

    在运行自己写的 C 多线程程序时 xff0c 出现 xff1a 已放弃 吐核 问题 出现这种问题一般是下面这几种情况 xff1a 1 内存越界 2 使用了非线程安全的函数 3 全局数据未加锁保护 4 非法指针 5 堆栈溢出 也就是需要检查访
  • Linux apt-get 安装离线包

    问题 在一些与外网隔离的系统中无法直接通过 apt get 的方式直接安装软件包 解决方案 可以通过 apt get download 提前下载好包及相关依赖 xff0c 然后通过 dpkg i 的方式离线安装 下载依赖 PACKAGE 代
  • 解决 free(): invalid pointer: 0x00000 运行时报错

    编译成功 xff0c 运行时报错 xff1a 在使用 pytorch or tensorflow or caffe 时 xff0c 都可能存在这个问题 xff1a Error in 96 xxx 39 free invalid pointe
  • Google Datastore 学习记录

    由于在google app engine 使用google cloud sql 是要收费的 xff0c 于是学习一下google提供的免费的非关系型数据库datastore 它的特点有 xff1a No planned downtime x
  • 诊断调试命令strace用法

    strace是什么 xff1f 按照strace官网的描述 strace是一个可用于诊断 调试和教学的Linux用户空间跟踪器 我们用它来监控用户空间进程和内核的交互 xff0c 比如系统调用 信号传递 进程状态变更等 strace底层使用