mirror of
https://github.com/danbulant/node-x11
synced 2026-06-16 21:21:20 +00:00
use property setter in debug mode to map seq num to stack trace
This commit is contained in:
parent
d436abf9b9
commit
56001da581
1 changed files with 46 additions and 25 deletions
71
lib/xcore.js
71
lib/xcore.js
|
|
@ -64,8 +64,26 @@ function XClient(stream, displayNum, screenNum, options)
|
|||
this.pack_stream = pack_stream;
|
||||
|
||||
this.rsrc_id = 0; // generated for each new resource
|
||||
this.seq_num = 0; // incremented in each request. (even if we don't expect reply)
|
||||
this.seq2stack = {}; // debug: map seq_num to stack at the moment request was issued
|
||||
var cli = this;
|
||||
if (cli.options.debug) {
|
||||
this.seq_num_ = 0;
|
||||
this.seq2stack = {}; // debug: map seq_num to stack at the moment request was issued
|
||||
Object.defineProperty(cli, "seq_num", {
|
||||
set : function(v) {
|
||||
cli.seq_num_ = v;
|
||||
var err = new Error();
|
||||
Error.captureStackTrace(err, arguments.callee);
|
||||
err.timestamp = Date.now();
|
||||
cli.seq2stack[client.seq_num] = err;
|
||||
},
|
||||
get: function() {
|
||||
return cli.seq_num_;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.seq_num = 0;
|
||||
}
|
||||
|
||||
|
||||
// in/out packets indexed by sequence ID
|
||||
this.replies = {};
|
||||
|
|
@ -83,6 +101,7 @@ function XClient(stream, displayNum, screenNum, options)
|
|||
|
||||
this.event_consumers = {}; // maps window id to eventemitter TODO: bad name
|
||||
this.eventParsers = {};
|
||||
this.errorParsers = {};
|
||||
|
||||
this.importRequestsFromTemplates(this, coreRequests);
|
||||
|
||||
|
|
@ -138,18 +157,6 @@ XClient.prototype.importRequestsFromTemplates = function(target, reqs)
|
|||
else
|
||||
client.seq_num++;
|
||||
|
||||
// disable long stack trace for the moment, it's too expensive
|
||||
// performance when enabled (travis-ci worker, Xfvb): 70000 requests finished in 52196 ms, 1341.0989347842747 req/sec
|
||||
// without: 70000 requests finished in 14904 ms, 4696.725711218465 req/sec
|
||||
// MBPro, XQuartz: with 3600 req/sec, without 24200 req/sec
|
||||
if (this.options.debug === true) {
|
||||
var err = new Error();
|
||||
err.name = reqName; //???
|
||||
Error.captureStackTrace(err, arguments.callee);
|
||||
err.timestamp = Date.now();
|
||||
client.seq2stack[client.seq_num] = err;
|
||||
}
|
||||
|
||||
// is it fast?
|
||||
var args = Array.prototype.slice.call(req_proxy.arguments);
|
||||
|
||||
|
|
@ -171,7 +178,7 @@ XClient.prototype.importRequestsFromTemplates = function(target, reqs)
|
|||
var value = req_proxy.arguments[1];
|
||||
if (client.atoms[value]) {
|
||||
-- client.seq_num;
|
||||
return process.nextTick(function() {
|
||||
return setImmediate(function() {
|
||||
callback(undefined, client.atoms[value]);
|
||||
});
|
||||
} else {
|
||||
|
|
@ -197,7 +204,7 @@ XClient.prototype.importRequestsFromTemplates = function(target, reqs)
|
|||
var atom = req_proxy.arguments[0];
|
||||
if (client.atom_names[atom]) {
|
||||
-- client.seq_num;
|
||||
return process.nextTick(function() {
|
||||
return setImmediate(function() {
|
||||
callback(undefined, client.atom_names[atom]);
|
||||
});
|
||||
} else {
|
||||
|
|
@ -412,12 +419,22 @@ XClient.prototype.expectReplyHeader = function()
|
|||
error.error = error_code;
|
||||
error.seq = seq_num;
|
||||
error.message = xerrors.errorText[error_code];
|
||||
if (client.options.debug)
|
||||
error.stack = client.seq2stack[error.seq]
|
||||
if (client.options.debug) {
|
||||
error.longstack = client.seq2stack[error.seq]
|
||||
console.log(client.seq2stack[error.seq].stack);
|
||||
}
|
||||
|
||||
// unpack error packet (32 bytes for all error types, 8 of them in CCSL header)
|
||||
client.pack_stream.get(24, function(buf) {
|
||||
|
||||
var extUnpacker = client.errorParsers[type];
|
||||
if (extUnpacker) {
|
||||
var event = extUnpacker(type, seq_num, bad_value, body);
|
||||
client.emit(error, event);
|
||||
client.expectReplyHeader();
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: dispatch, use sequence number
|
||||
//TODO: add more generic way to read common values
|
||||
// if (error_code == 14)
|
||||
|
|
@ -569,26 +586,30 @@ module.exports.createClient = function(options, initCb)
|
|||
var client = new XClient(stream, displayNum, screenNum, options);
|
||||
if (initCb)
|
||||
{
|
||||
var cbCalled = false;
|
||||
client.on('connect', function(display) {
|
||||
// Once connected don't call initCb on error, just emit
|
||||
stream.removeListener('error', initCb);
|
||||
stream.on('error', function(err) {
|
||||
client.emit('error', err);
|
||||
});
|
||||
// opt-in BigReq
|
||||
if (!options.disableBigRequests) {
|
||||
client.require('big-requests', function(BigReq) {
|
||||
BigReq.Enable(function(err, maxLen) {
|
||||
display.max_request_length = maxLen;
|
||||
cbCalled = true;
|
||||
initCb(undefined, display);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
cbCalled = true;
|
||||
initCb(undefined, display);
|
||||
}
|
||||
});
|
||||
|
||||
stream.on('error', initCb);
|
||||
stream.on('error', function(err) {
|
||||
if (cbCalled)
|
||||
client.emit('error', err);
|
||||
else {
|
||||
cbCalled = true;
|
||||
initCb(err);
|
||||
}
|
||||
});
|
||||
}
|
||||
return client;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue