public inbox for systemtap@sourceware.org
 help / color / mirror / Atom feed
* Working on systemtap equivalent to bcc ucalls.py
@ 2018-11-14 16:07 William Cohen
  0 siblings, 0 replies; only message in thread
From: William Cohen @ 2018-11-14 16:07 UTC (permalink / raw)
  To: systemtap

[-- Attachment #1: Type: text/plain, Size: 3452 bytes --]

Hi,

I have been working a Systemtap script that implements similar functionality to bcc's ucalls (https://github.com/iovisor/bcc/blob/master/tools/lib/ucalls.py).  The systemtap script will count the number of function/method calls for java/python/perl/php/ruby/tcl code pointed at by the -x <pid> or -c <command> options.  It also takes an optional argument for the number of seconds between reports.  One can also control the number of printed by setting the TOP variable on the command line.  So something like this monitoring "dnf debuginfo-install kernel-4.18.17-200.fc28.x86_64"


$ ./profiling/ucalls.stp -x 22952  -G TOP=10 10
Missing separate debuginfos, use: debuginfo-install kernel-core-4.18.17-200.fc28.x86_64 
METHOD                                              # CALLS
/usr/lib/python3.6/site-packages/dnf/cli/progress.py.progress       20
/usr/lib/python3.6/site-packages/dnf/cli/format.py.format_number       20
/usr/lib64/python3.6/posixpath.py.basename               20
/usr/lib/python3.6/site-packages/dnf/repo.py._progress_cb       20
/usr/lib/python3.6/site-packages/dnf/repo.py.download_size       20
/usr/lib/python3.6/site-packages/dnf/repo.py.__str__       20
/usr/lib64/python3.6/posixpath.py._get_sep               20
/usr/lib/python3.6/site-packages/dnf/cli/progress.py._update       10
/usr/lib/python3.6/site-packages/dnf/cli/progress.py.message       10
/usr/lib/python3.6/site-packages/dnf/cli/format.py.format_time       10

METHOD                                              # CALLS
/usr/lib/python3.6/site-packages/dnf/cli/progress.py.progress       20
/usr/lib/python3.6/site-packages/dnf/cli/format.py.format_number       20
/usr/lib64/python3.6/posixpath.py.basename               20
/usr/lib/python3.6/site-packages/dnf/repo.py._progress_cb       20
/usr/lib/python3.6/site-packages/dnf/repo.py.download_size       20
/usr/lib/python3.6/site-packages/dnf/repo.py.__str__       20
/usr/lib64/python3.6/posixpath.py._get_sep               20
/usr/lib/python3.6/site-packages/dnf/cli/progress.py._update       10
/usr/lib/python3.6/site-packages/dnf/cli/progress.py.message       10
/usr/lib/python3.6/site-packages/dnf/cli/format.py.format_time       10

There are a number of other options that the bcc ucalls has that are not implemented in this systemtap script:

language "-l" <language>  : this isn't needed in the systemtap script.  systemtap optional probes allow automatic selection of the language

Latency "-L": this is possible and considering adding this.  However, the ucalls doesn't handle recursive functions.

Report syscalls "-S"  this should also be easy to add.  Need to see how ucalls outputs this.

Report in milliseconds "-m" : this didn't seem that important


One of the things I noticed when running the script with the periodic updates is that it will exist due to exceeding the overhead limits.  I think it is because the handler printing out the data takes a substantial amount of time and locks the associative array will working on it, causing the overhead to go up quite a bit for all the probes that are collecting data.

It would be nice if systemtap had some mechanism kind of like double buffering used for video displays.  Two entries for associative arrays: one for the data collection and the other for the display.  They are swapped when then time probe handler runs.  This would allow the reporting to lock the associative arrays for a much shorter period of time.

-Will

[-- Attachment #2: ucalls.stp --]
[-- Type: text/plain, Size: 1484 bytes --]

#! /usr/bin/env stap
#
# Copyright (C) 2018 Red Hat, Inc.
# By William cohen, Red Hat Inc.
# wcohen@redhat.com
#

global tally
global TOP = 100000 // -G TOP=10 to get top 10

# probes for java
probe hotspot.method_entry? {
  if (pid() != target()) next
  tally[class, name] <<< 1
}

# probes for perl
probe perl.sub.call? {
  if (pid() != target()) next
  tally[filename, sub] <<< 1
}

# probes for php
probe process("php").mark("function__entry")? {
  if (pid() != target()) next
  class = user_string($arg4)
  method = user_string($arg1)
  tally[class, method] <<< 1
}

# probes for python
probe process("/usr/lib*/libpython*.so.1.0").mark("function__entry")? {
  if (pid() != target()) next
  class = user_string($arg1)
  method = user_string($arg2)
  tally[class, method] <<< 1
}

# probes for ruby
probe ruby.method.entry? {
  if (pid() != target()) next
  tally[classname, methodname] <<< 1
}

# probes for tcl
# TODO cmd__entry ?
probe process("/usr/lib*/libtcl*.so").mark("proc__entry")? {
  if (pid() != target()) next
  class = ""
  method = user_string($arg1)
  tally[class, method] <<< 1
}

function print_info() {
  printf("%-50s %8s\n", "METHOD", "# CALLS")
  foreach([class, method] in tally- limit TOP){
    class_method = sprintf("%s.%s", class, method)
    printf("%-50s %8d\n", class_method, @sum(tally[class, method]))
  }
  printf("\n")
}

# optional periodic timer timer argument
%( $# > 0 %?
probe timer.s($1)
%:
probe end
%)
{
  print_info()
  delete tally
}


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2018-11-14 16:07 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-11-14 16:07 Working on systemtap equivalent to bcc ucalls.py William Cohen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).