Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

add input filter for umem_cache bufctl stacks #8

Open
wants to merge 1 commit into from

2 participants

@tjfontaine

No description provided.

@davepacheco davepacheco commented on the diff
lib/input-umem-cache.js
((41 lines not shown))
+ this.dsr_log = log;
+ this.dsr_linenum = 0;
+ this.dsr_sline = 0;
+ this.dsr_stack = [];
+ this.dsr_carrier = mod_carrier.carry(input);
+ this.dsr_carrier.on('line', this.onLine.bind(this));
+ this.dsr_carrier.on('end', this.onEnd.bind(this));
+
+ mod_events.EventEmitter.call(this);
+}
+
+mod_util.inherits(UmemStreamReader, mod_events.EventEmitter);
+
+UmemStreamReader.prototype.onLine = function (line)
+{
+ /* The first two lines are always ignored. */
@davepacheco Owner

Are there actually two lines ignored in addition to the two lines you're ignoring with each stack?

right so there is a 2 line header for the file in general, and then each sample has a 2 line header

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@davepacheco davepacheco commented on the diff
lib/input-umem-cache.js
((26 lines not shown))
+ */
+
+
+var mod_util = require('util');
+var mod_events = require('events');
+
+var mod_carrier = require('carrier');
+
+/* We always ignore the first 2 lines. */
+var NHEADERLINES = 2;
+
+exports.reader = UmemStreamReader;
+
+function UmemStreamReader(input, log)
+{
+ this.dsr_log = log;
@davepacheco Owner

Change the prefix to "usr"?

indeed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@davepacheco
Owner

I'm pretty torn about whether it would be worthwhile to commonize some of this code with the code for the DTrace reader. Obviously a fair bit overlaps, but it's intertwined with a bunch of code that's legitimately different. You could extract a few utility functions for stripping function and template arguments and the like, but the complexity (and obfuscation) of an abstract base class to manage the overall control flow may not be worth saving the few LOC involved.

Could you document (even if just in a comment here) what inputs you tested, ideally with some example frames? I may one day refactor the code and it will be useful to have sample input to regression test against.

Thanks for the feature!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Nov 1, 2013
  1. @tjfontaine
This page is out of date. Refresh to see the latest.
Showing with 121 additions and 0 deletions.
  1. +121 −0 lib/input-umem-cache.js
View
121 lib/input-umem-cache.js
@@ -0,0 +1,121 @@
+/*
+ * lib/input-umem-cache.js: reads output from an mdb ::bufctl -v, which emits
+ * stanzas that look like this:
+ *
+ * ffeca50 10001000 401f50b1339a6a 1
+ * 8f73010 0 0
+ * libumem.so.1`umem_cache_alloc_debug+0x144
+ * libumem.so.1`umem_cache_alloc+0x19a
+ * libumem.so.1`umem_alloc+0xcd
+ * libumem.so.1`malloc+0x2a
+ * libstdc++.so.6.0.17`_Znwj+0x29
+ * libstdc++.so.6.0.17`_Znaj+0x1d
+ * _ZN2v88internal11HandleScope6ExtendEv+0xdf
+ * _ZN2v88internal8JSObject20SetPropertyForResultEPNS0_12LookupResultEPNS0_6StringEPNS0_6ObjectE18PropertyAttributesNS0_14StrictModeFlagENS0_10JSReceiver14StoreFromKeyedE+0x5f8
+ * _ZN2v88internal10JSReceiver11SetPropertyEPNS0_6StringEPNS0_6ObjectE18PropertyAttributesNS0_14StrictModeFlagENS1_14StoreFromKeyedE+0x8d
+ * _ZN2v88internal7StoreIC5StoreENS0_16InlineCacheStateENS0_14StrictModeFlagENS0_6HandleINS0_6ObjectEEENS4_INS0_6StringEEES6_+0x359
+ * _ZN2v88internal12StoreIC_MissENS0_9ArgumentsEPNS0_7IsolateE+0x139
+ * 0xa3c0a376
+ * 0xbf54e125
+ * 0xbf573d62
+ * 0xbf573c93
+ *
+ * You can generate such output with:
+ *
+ * > ::walk bufctl | ::bufctl -v ! cat > stacks.out
+ */
+
+
+var mod_util = require('util');
+var mod_events = require('events');
+
+var mod_carrier = require('carrier');
+
+/* We always ignore the first 2 lines. */
+var NHEADERLINES = 2;
+
+exports.reader = UmemStreamReader;
+
+function UmemStreamReader(input, log)
+{
+ this.dsr_log = log;
@davepacheco Owner

Change the prefix to "usr"?

indeed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ this.dsr_linenum = 0;
+ this.dsr_sline = 0;
+ this.dsr_stack = [];
+ this.dsr_carrier = mod_carrier.carry(input);
+ this.dsr_carrier.on('line', this.onLine.bind(this));
+ this.dsr_carrier.on('end', this.onEnd.bind(this));
+
+ mod_events.EventEmitter.call(this);
+}
+
+mod_util.inherits(UmemStreamReader, mod_events.EventEmitter);
+
+UmemStreamReader.prototype.onLine = function (line)
+{
+ /* The first two lines are always ignored. */
@davepacheco Owner

Are there actually two lines ignored in addition to the two lines you're ignoring with each stack?

right so there is a 2 line header for the file in general, and then each sample has a 2 line header

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ if (++this.dsr_linenum <= NHEADERLINES)
+ return;
+
+ /* ignore ADDR, BUFADDR, TIMESTAMP, THREAD, CACHE, LASTLOG, CONTENTS */
+ if (++this.dsr_sline <= NHEADERLINES)
+ return;
+
+ if (!line.trim()) {
+ if (this.dsr_stack.length === 0) {
+ this.dsr_log.warn('line ' + this.dsr_linenum +
+ ': found count with no stack');
+ return;
+ }
+
+ this.emit('stack', this.dsr_stack, 1);
+ this.dsr_stack = [];
+ this.dsr_sline = 0;
+ return;
+ }
+
+ /*
+ * In general, lines may have leading or trailing whitespace and the
+ * following components:
+ *
+ * module`function+offset
+ *
+ * We try to avoid assuming too much about the form in order to support
+ * various annotations provided by ustack helpers, but we want to strip
+ * off the offset.
+ */
+ var frame = line;
+ frame = frame.replace(/^\s+/, '');
+ frame = frame.replace(/\s+$/, '');
+ /* JSSTYLED */
+ frame = frame.replace(/\+.*/, '');
+
+ /* maybe configurable? */
+ frame = frame.replace(/^0x[a-f0-9]{8}$/, '<unknown>');
+
+ /*
+ * Remove both function and template parameters from demangled C++
+ * frames, but skip the first two characters because they're used by the
+ * Node.js ustack helper as separators.
+ */
+ /* JSSTYLED */
+ frame = frame.replace(/(..)[(<].*/, '$1');
+
+ if (line.length === 0) {
+ if (this.dsr_stack.length !== 0)
+ this.dsr_log.warn('line ' + this.dsr_linenum +
+ ': unexpected blank line');
+ return;
+ }
+
+ this.dsr_stack.unshift(frame);
+};
+
+UmemStreamReader.prototype.onEnd = function ()
+{
+ if (this.dsr_stack.length !== 0)
+ this.dsr_log.warn('line ' + this.dsr_linenum +
+ ': unexpected end of stream');
+
+ this.emit('end');
+};
Something went wrong with that request. Please try again.