From 6bb8047db6b04823c91fe96deb665d524ff074e3 Mon Sep 17 00:00:00 2001 From: adelphes Date: Thu, 26 Jan 2017 17:58:37 +0000 Subject: [PATCH] Stop the Android runtime from barfing into logcat Split field retrieval into statics and instances --- src/debugger.js | 30 +++++++++++++++++++++++++++--- src/jdwp.js | 26 +++++++++++++++++++++++++- 2 files changed, 52 insertions(+), 4 deletions(-) diff --git a/src/debugger.js b/src/debugger.js index 7de07ed..312a360 100644 --- a/src/debugger.js +++ b/src/debugger.js @@ -794,14 +794,38 @@ Debugger.prototype = { }) .then(function (typeinfo, x) { x.typeinfo = typeinfo; + // the Android runtime now pointlessly barfs into logcat if an instance value is used + // to retrieve a static field. So, we now split into two calls... + x.splitfields = typeinfo.fields.reduce((z,f) => { + if (f.modbits & 8) z.static.push(f); else z.instance.push(f); + return z; + }, {instance:[],static:[]}); + // if there are no instance fields, just resolve with an empty array + if (!x.splitfields.instance.length) + return $.Deferred().resolveWith(this,[[], x]); return this.session.adbclient.jdwp_command({ ths: this, extra: x, - cmd: this.JDWP.Commands.GetFieldValues(x.objvar.value, typeinfo.fields), + cmd: this.JDWP.Commands.GetFieldValues(x.objvar.value, x.splitfields.instance), }); }) - .then(function (fieldvalues, x) { - return this._mapvalues('field', x.typeinfo.fields, fieldvalues, { objvar: x.objvar }, x); + .then(function (instance_fieldvalues, x) { + x.instance_fieldvalues = instance_fieldvalues; + // and now the statics (with a type reference) + if (!x.splitfields.static.length) + return $.Deferred().resolveWith(this,[[], x]); + return this.session.adbclient.jdwp_command({ + ths: this, + extra: x, + cmd: this.JDWP.Commands.GetStaticFieldValues(x.splitfields.static[0].typeid, x.splitfields.static), + }); + }) + .then(function (static_fieldvalues, x) { + x.static_fieldvalues = static_fieldvalues; + // make sure the fields and values match up... + var fields = x.splitfields.instance.concat(x.splitfields.static); + var values = x.instance_fieldvalues.concat(x.static_fieldvalues); + return this._mapvalues('field', fields, values, { objvar: x.objvar }, x); }) .then(function (res, x) { for (var i = 0; i < res.length; i++) { diff --git a/src/jdwp.js b/src/jdwp.js index 6c9b104..ac2ecea 100644 --- a/src/jdwp.js +++ b/src/jdwp.js @@ -627,6 +627,28 @@ function _JDWP() { } ); }, + GetStaticFieldValues:function(typeid, fields) { + return new Command('GetStaticFieldValues:'+typeid, 2, 6, + function() { + var res=[]; + DataCoder.encodeRef(res, typeid); + DataCoder.encodeInt(res, fields.length); + for (var i in fields) { + DataCoder.encodeRef(res, fields[i].fieldid); + } + return res; + }, + function(o) { + var res = []; + var arrlen = DataCoder.decodeInt(o); + while (--arrlen>=0) { + var v = DataCoder.decodeValue(o); + res.push(v); + } + return res; + } + ); + }, sourcefile:function(ci) { return new Command('SourceFile:'+ci.name, 2, 7, function() { @@ -650,7 +672,9 @@ function _JDWP() { var arrlen = DataCoder.decodeInt(o); var res = []; while (--arrlen>=0) { - res.push(DataCoder.decodeList(o, [{fieldid:'fref'},{name:'string'},{type:'signature'},{genericsig:'string'},{modbits:'int'}])); + var field = DataCoder.decodeList(o, [{fieldid:'fref'},{name:'string'},{type:'signature'},{genericsig:'string'},{modbits:'int'}]); + field.typeid = ci.info.typeid; + res.push(field); } return res; }