mirror of
https://github.com/danbulant/node-x11
synced 2026-07-05 03:00:42 +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.pack_stream = pack_stream;
|
||||||
|
|
||||||
this.rsrc_id = 0; // generated for each new resource
|
this.rsrc_id = 0; // generated for each new resource
|
||||||
this.seq_num = 0; // incremented in each request. (even if we don't expect reply)
|
var cli = this;
|
||||||
this.seq2stack = {}; // debug: map seq_num to stack at the moment request was issued
|
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
|
// in/out packets indexed by sequence ID
|
||||||
this.replies = {};
|
this.replies = {};
|
||||||
|
|
@ -83,6 +101,7 @@ function XClient(stream, displayNum, screenNum, options)
|
||||||
|
|
||||||
this.event_consumers = {}; // maps window id to eventemitter TODO: bad name
|
this.event_consumers = {}; // maps window id to eventemitter TODO: bad name
|
||||||
this.eventParsers = {};
|
this.eventParsers = {};
|
||||||
|
this.errorParsers = {};
|
||||||
|
|
||||||
this.importRequestsFromTemplates(this, coreRequests);
|
this.importRequestsFromTemplates(this, coreRequests);
|
||||||
|
|
||||||
|
|
@ -138,18 +157,6 @@ XClient.prototype.importRequestsFromTemplates = function(target, reqs)
|
||||||
else
|
else
|
||||||
client.seq_num++;
|
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?
|
// is it fast?
|
||||||
var args = Array.prototype.slice.call(req_proxy.arguments);
|
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];
|
var value = req_proxy.arguments[1];
|
||||||
if (client.atoms[value]) {
|
if (client.atoms[value]) {
|
||||||
-- client.seq_num;
|
-- client.seq_num;
|
||||||
return process.nextTick(function() {
|
return setImmediate(function() {
|
||||||
callback(undefined, client.atoms[value]);
|
callback(undefined, client.atoms[value]);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -197,7 +204,7 @@ XClient.prototype.importRequestsFromTemplates = function(target, reqs)
|
||||||
var atom = req_proxy.arguments[0];
|
var atom = req_proxy.arguments[0];
|
||||||
if (client.atom_names[atom]) {
|
if (client.atom_names[atom]) {
|
||||||
-- client.seq_num;
|
-- client.seq_num;
|
||||||
return process.nextTick(function() {
|
return setImmediate(function() {
|
||||||
callback(undefined, client.atom_names[atom]);
|
callback(undefined, client.atom_names[atom]);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -412,12 +419,22 @@ XClient.prototype.expectReplyHeader = function()
|
||||||
error.error = error_code;
|
error.error = error_code;
|
||||||
error.seq = seq_num;
|
error.seq = seq_num;
|
||||||
error.message = xerrors.errorText[error_code];
|
error.message = xerrors.errorText[error_code];
|
||||||
if (client.options.debug)
|
if (client.options.debug) {
|
||||||
error.stack = client.seq2stack[error.seq]
|
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)
|
// unpack error packet (32 bytes for all error types, 8 of them in CCSL header)
|
||||||
client.pack_stream.get(24, function(buf) {
|
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: dispatch, use sequence number
|
||||||
//TODO: add more generic way to read common values
|
//TODO: add more generic way to read common values
|
||||||
// if (error_code == 14)
|
// if (error_code == 14)
|
||||||
|
|
@ -569,26 +586,30 @@ module.exports.createClient = function(options, initCb)
|
||||||
var client = new XClient(stream, displayNum, screenNum, options);
|
var client = new XClient(stream, displayNum, screenNum, options);
|
||||||
if (initCb)
|
if (initCb)
|
||||||
{
|
{
|
||||||
|
var cbCalled = false;
|
||||||
client.on('connect', function(display) {
|
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
|
// opt-in BigReq
|
||||||
if (!options.disableBigRequests) {
|
if (!options.disableBigRequests) {
|
||||||
client.require('big-requests', function(BigReq) {
|
client.require('big-requests', function(BigReq) {
|
||||||
BigReq.Enable(function(err, maxLen) {
|
BigReq.Enable(function(err, maxLen) {
|
||||||
display.max_request_length = maxLen;
|
display.max_request_length = maxLen;
|
||||||
|
cbCalled = true;
|
||||||
initCb(undefined, display);
|
initCb(undefined, display);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
cbCalled = true;
|
||||||
initCb(undefined, display);
|
initCb(undefined, display);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
stream.on('error', function(err) {
|
||||||
stream.on('error', initCb);
|
if (cbCalled)
|
||||||
|
client.emit('error', err);
|
||||||
|
else {
|
||||||
|
cbCalled = true;
|
||||||
|
initCb(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue