我目前正在分析我的node.js应用程序.我发现这个博客:http://blog.nodejs.org/2012/04/25/profiling-node-js/表明我应该使用Dtrace.我使用以下步骤在ubuntu 12.04上安装了dtrace:https://askubuntu.com/questions/60940/how-do-i-install-dtrace
但是,当我在节点应用程序运行时在终端中运行此命令时:
dtrace -o stacks.out -n 'profile-97/execname == "node" && arg1/{
@[jstack(100, 8000)] = count(); } tick-60s { exit(0); }'
Run Code Online (Sandbox Code Playgroud)
stacks.out保持空白,除了:CPU ID FUNCTION:NAME 1 387695:tick-60s
有什么建议可能有什么不对吗?
我正在尝试通过 libdtrace 使用 dtrace(在 Snow Leopard 上;10.6.4)。我想在我自己的程序中捕获我的 dtrace 脚本的打印输出。一种方法是将输出转到临时文件并从那里读取。但是,libdtrace 支持回调函数来直接捕获我更喜欢的输出。
我认为回调只会传递我可以使用的格式化字符串,但情况似乎并非如此。例如,在下面的测试程序中,我希望打印输出为“process pid = 86138”。但是,它总是打印出“process pid = 1”(当使用 'dtrace -n' 运行时,dtrace 脚本工作正常)。
我究竟做错了什么 ?我应该如何使用传递给缓冲区处理程序的数据?(具体来说,来自 printf 和 tracemem 操作的数据是我感兴趣的)。
#include <dtrace.h>
#include <stdio.h>
#include <stdlib.h>
#include <mach/mach.h>
#include <mach-o/loader.h>
#include <mach-o/dyld.h>
#include <mach-o/fat.h>
#include <sys/sysctl.h>
#include <signal.h>
static const char *g_prog =
"pid86138::write:entry"
"{"
" printf(\"process pid = %d\\n\", pid);"
"}";
static int dcmdbuffered(const dtrace_bufdata_t *bufdata, void *arg) {
if((bufdata->dtbda_recdesc != NULL) && (bufdata->dtbda_recdesc->dtrd_action == DTRACEACT_PRINTF))
printf("BUF: %s\n", bufdata->dtbda_buffered);
return DTRACE_HANDLE_OK;
} …
Run Code Online (Sandbox Code Playgroud) 我有一个2009年中期的MacBook Pro和一个新的2012 MacBook Pro,我正在学习DTrace(一个非常神奇的工具).当我计算新的2012 MBP上的聚合时,聚合不会打印出来.
sudo dtrace -n 'syscall:::entry { @[execname] = count() }'
Run Code Online (Sandbox Code Playgroud)
在我2009年中期的MBP上,它显示了类似于:
usbmuxd 1
GrowlHelperApp 2
imklaunchagent 2
installd 2
stackshot 2
...
Run Code Online (Sandbox Code Playgroud)
2012 MBP没有显示任何内容.
我在BEING和END探针中添加了一个printf,看看END探针是否会像这样发射:
BEGIN
{
printf("Hi!");
}
syscall:::entry
{
@[execname] = count();
}
END
{
printf("Bye!")
}
Run Code Online (Sandbox Code Playgroud)
在2009年中期,MBP两种探测器都被发射和打印,而在2012 MBP上,只有BEGIN探测器被发射.END从未解雇过.
两个MBP都在运行Lion 10.7.3.我不确定下一步该尝试什么.现在想到的唯一区别是我没有在2012 MBP上安装开发人员命令行工具.这对我来说没有意义,而且是在黑暗中拍摄.
任何帮助或想法将不胜感激.谢谢.
============= [启用Root帐户] ====================
所以我启用了root帐户并重新运行了命令
sudo dtrace -n 'syscall:::entry { @[execname] = count() }'
Run Code Online (Sandbox Code Playgroud)
没有成功,但如果我这样做
su
dtrace -n 'syscall:::entry { @[execname] = count() }'
Run Code Online (Sandbox Code Playgroud)
有用!
============= [kill -s INT] =============================
我做了一些实验.如果我跑:
sudo …
Run Code Online (Sandbox Code Playgroud) 标题说得最多,真的.在Linux上这将是很容易与strace
和可能的lsof
或/proc
,并用它很容易在OSX,直到truss
从OSX Leopard的去除,与潜在的系统调用(据我所知)一起.
显而易见的方法是用这个问题来解决这个问题dtrace
,但据我所知,dtrace
这不会做,因为它会在事件发生时捕获事件 - 在我的情况下,阻塞系统调用已经开始了.dtrace
顺便说一下,如果可以解决这个问题,我很乐意做出纠正.
我看到Xcode的仪器有一个监视器,通过定期处理进程堆栈的样本来实现类似的东西(不确定系统调用依赖于它做什么!),也许在命令行上类似的东西就足够了(因为它会显示堆栈一直到包含系统调用的库调用).为了对我的用例有用,这个"采样命令行工具"必须找到并解析它在堆栈上找到的参数,以便确定我们阻止了哪些文件/文件描述符.
最后一件事 - 在Linux上,你通常可以做普通用户(假设没有ptrace_scope
技巧).如果OSX解决方案也不需要root,那将是很好的.
我希望能够测试对各种命令行实用程序的内存复杂性的一些猜测。
举个简单的例子
grep pattern file
Run Code Online (Sandbox Code Playgroud)
我想看看内存使用如何随 的大小pattern
和file
.
对于时间复杂度,我会猜测,然后运行
time grep pattern file
Run Code Online (Sandbox Code Playgroud)
在各种大小的输入上,看看我的猜测是否在现实中得到证实,但我不知道如何为记忆做到这一点。
一种可能性是使用包装脚本启动作业并定期对内存使用情况进行采样,但这似乎不雅,不太可能给出真正的高水印。
我已经看到了time -v
建议,但我的机器上没有该标志(在 OSX 上运行 bash)并且不知道在哪里可以找到支持它的版本。
我还看到,在 Linux 上,此信息可通过proc
文件系统获得,但同样,在我的上下文中无法获得。
我想知道是否dtrace
可能是一个合适的工具,但再次担心一个简单的基于样本的数字可能不是真正的高水印?
有谁知道适合 OSX 的工具或方法吗?
编辑
我删除了两次提到的磁盘使用情况,这只是旁白,可能会分散问题的主旨。
我已经配置并安装了Ruby 2.2.2并启用了DTrace(--enable-dtrace
).
它似乎成功地完成了:"检查dtrace USDT是否可用......是"和"dtrace"在另一个支票上(而不是"否").
测试:
sudo dtrace -c 'ruby -v' -l -m ruby
返回:
dtrace: failed to match :ruby::: No probe matches description
我确实看到yosemite系统ruby上缺少dtrace探测器,但那是RVM,我使用本地用户帐户安装(sudo-less).
是否有类似配置的人使这项工作,如果是这样,如何?
谢谢.
另外:IRB的RbConfig::CONFIG['DTRACE']
输出dtrace
.
我已经用谷歌搜索了DDG这个问题,所以我认为根据自己的经验给出答案是必要的,以帮助......
我有一个在 aws ubuntu 实例上运行的 node.js 应用程序。我试图生成火焰图dtrace
,linux perf tools
但它们似乎都不起作用。这些是我遵循的步骤:
linux性能工具:https : //www.carlhopf.com/blog/2016/09/11/nodejs-cpu-profiling-production/
dtrace: https://nodejs.org/en/blog/uncategorized/profiling-node-js/
我已经--prof / --perf_basic_prof_only_functions
为 linux perf 工具命令添加了启动应用程序的同时。
我从 dtrace stacks.out 文件得到的输出是:
CPU ID FUNCTION:NAME
0 330511 :tick-60s
Run Code Online (Sandbox Code Playgroud)
安装dtrace
如下:https : //askubuntu.com/questions/60940/how-do-i-install-dtrace
当我尝试将 linux perf 命令的输出转换为火焰图时得到的输出是
ERROR: No stack counts found
Run Code Online (Sandbox Code Playgroud)
我不确定缺少什么以及为什么没有记录堆栈跟踪。
node version: 8.4.0
ubuntu : 14.04
我确实看到有Systemtap
可用选项并且可以使用此命令:
stap -s 32 -D MAXBACKTRACE=100 -D MAXSTRINGLEN=4096 -D MAXMAPENTRIES=10240 \
-D MAXACTION=10000 -D STP_OVERLOAD_THRESHOLD=5000000000 --all-modules \
-ve 'global s; …
Run Code Online (Sandbox Code Playgroud) 我最近决定学习更多关于系统编程的知识,并且觉得看看我的代码实际上在做什么是很有帮助的.
为此,我在C++中编写了一个简短的LinkedList类,并决定使用它来跟踪它dtruss
(读取:dtrace).
我的期望是任何扩展堆的指令(例如使用new
关键字或实例化LinkedList对象)都会调用mmap
或sbrk
/ break
系统调用.此情况并非如此!
实际上,dtruss
使用-s开关运行时,我看不到从我的函数内部调用任何系统调用LinkedList::Add
!测试,我正在添加某些元素.
任何人都可以解释为什么我没有看到mmap
/ sbrk
在我的dtruss输出中的引用?
奖励积分,如果有人可以解释的目的mprotect
和madvise
.
我在下面包含了我的LinkedList类,main.cpp和dtruss输出.
谢谢!
dtruss输出
SYSCALL(args) = return
Created new LinkedList
Created new LinkedList
Destroyed a LinkedList
open("/dev/dtracehelper\0", 0x2, 0xFFFFFFFFE3236D70) = 3 0
ioctl(0x3, 0x80086804, 0x7FFEE3236CD0) = 0 0
close(0x3) = 0 0
access("/AppleInternal/XBS/.isChrooted\0", 0x0, 0x0) = -1 Err#2
thread_selfid(0x0, 0x0, 0x0) = 198178 0
bsdthread_register(0x7FFF5BAB5C50, 0x7FFF5BAB5C40, 0x2000) = 1073742047 …
Run Code Online (Sandbox Code Playgroud) 因此,我按照此链接将 BPF 程序附加到用户空间探针,Dtrace 格式(请参阅用户静态定义的跟踪点部分)。
C程序:
#include <sys/sdt.h>
int main() {
DTRACE_PROBE("hello-usdt", "probe-main");
}
Run Code Online (Sandbox Code Playgroud)
确保包含探测信息的检查:
readelf -n hello_usdt
stapsdt 0x00000033 NT_STAPSDT (SystemTap probe descriptors)
Provider: "hello_usdt"
Name: "probe-main"
Location: 0x0000000000400535, Base: 0x00000000004005d4, Semaphore: 0x0000000000000000
Arguments:
Run Code Online (Sandbox Code Playgroud)
还有 tplist:
sudo /usr/share/bcc/tools/tplist -l /path/to/hello_usdt
/path/to/hello_usdt "hello_usdt":"probe-main"
Run Code Online (Sandbox Code Playgroud)
BPF程序的内容(usdt.py):
readelf -n hello_usdt
stapsdt 0x00000033 NT_STAPSDT (SystemTap probe descriptors)
Provider: "hello_usdt"
Name: "probe-main"
Location: 0x0000000000400535, Base: 0x00000000004005d4, Semaphore: 0x0000000000000000
Arguments:
Run Code Online (Sandbox Code Playgroud)
故障描述:
sudo ./usdt.py
Traceback (most recent call last):
File "./usdt.py", line 13, in <module>
usdt.enable_probe(probe …
Run Code Online (Sandbox Code Playgroud) 我想知道open(2)
bash 脚本中进行了哪些调用。
我编写了以下拦截系统调用的程序:
#include <fcntl.h>
#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
#define DYLD_INTERPOSE(_replacment,_replacee) \
__attribute__((used)) static struct{ const void* replacment; const void* replacee; } _interpose_##_replacee \
__attribute__ ((section ("__DATA,__interpose"))) = { (const void*)(unsigned long)&_replacment, (const void*)(unsigned long)&_replacee };
static
int
my_open(const char *filename, int oflag, mode_t mode)
{
printf("$jason$ open: %s\n", filename);
return open(filename, oflag, mode);
}
DYLD_INTERPOSE(my_open, open)
Run Code Online (Sandbox Code Playgroud)
然后我使用以下命令运行:
clang -dynamiclib libfile.c -o libfile.dylib
export DYLD_INSERT_LIBRARIES=libfile.dylib
touch /tmp/testingtesting
Run Code Online (Sandbox Code Playgroud)
这不起作用。
我用自己编译的程序尝试了一下,效果很好。我用brew编译的程序尝试了一下,效果很好。我阅读了touch.c的源代码。它调用open(2)
.
然后我禁用了 …