4 Commits

Author SHA1 Message Date
adelphes
baa3fb6bfd version 0.3.1
bug fix release
2017-02-02 20:13:37 +00:00
adelphes
3cda2e5f1f Fix issue with exception breaks hanging
Temporarily resume the thread used to invoke toString() and re-suspend after.
2017-02-02 20:04:04 +00:00
adelphes
dfed765d21 Fix issue with crash on exception break 2017-02-02 19:19:20 +00:00
adelphes
b60ef65803 Fix issue with Android source not displaying
VSCode 1.9 prioritises srcref over path - we now set the ref to 0 if a source path is set.
2017-02-02 19:18:54 +00:00
4 changed files with 45 additions and 13 deletions

View File

@@ -1,5 +1,10 @@
# Change Log # Change Log
### version 0.3.1
* Bug fixes
* Fix issue with exception breaks crashing debugger
* Fix issue with Android sources not displaying in VSCode 1.9
## version 0.3.0 ## version 0.3.0
* Support for Logcat filtering using regular expressions * Support for Logcat filtering using regular expressions
* Improved expression parsing with support for arithmetic, bitwise, logical and relational operators * Improved expression parsing with support for arithmetic, bitwise, logical and relational operators

View File

@@ -2,7 +2,7 @@
"name": "android-dev-ext", "name": "android-dev-ext",
"displayName": "Android", "displayName": "Android",
"description": "Android debugging support for VS Code", "description": "Android debugging support for VS Code",
"version": "0.3.0", "version": "0.3.1",
"publisher": "adelphes", "publisher": "adelphes",
"preview": true, "preview": true,
"license": "MIT", "license": "MIT",

View File

@@ -802,7 +802,7 @@ class AndroidDebugSession extends DebugSession {
const srcpath = pkginfo ? path.join(pkginfo.package_path,sourcefile) const srcpath = pkginfo ? path.join(pkginfo.package_path,sourcefile)
: this._android_sources_path ? srcInfo.filepath : this._android_sources_path ? srcInfo.filepath
: null; : null;
const src = new Source(sourcefile, srcpath, srcRefId); const src = new Source(sourcefile, srcpath, srcpath ? 0 : srcRefId);
pkginfo && (highest_known_source=i); pkginfo && (highest_known_source=i);
stack.push(new StackFrame(stack_frame_id, name, src, linenum, 0)); stack.push(new StackFrame(stack_frame_id, name, src, linenum, 0));
} }

View File

@@ -142,6 +142,7 @@ Debugger.prototype = {
preparedclasses: [], preparedclasses: [],
stepids: {}, // hashmap<threadid,stepid> stepids: {}, // hashmap<threadid,stepid>
suspendcount: 0, // refcount of suspend-all-threads suspendcount: 0, // refcount of suspend-all-threads
threadsuspends: [], // hashmap<threadid, suspend-count>
} }
return this; return this;
}, },
@@ -462,12 +463,13 @@ Debugger.prototype = {
}, },
suspendthread: function (threadid, extra) { suspendthread: function (threadid, extra) {
return this.ensureconnected(extra) return this.ensureconnected({threadid,extra})
.then(function (extra) { .then(function (x) {
this.session.threadsuspends[x.threadid] = (this.session.threadsuspends[x.threadid]|0) + 1;
return this.session.adbclient.jdwp_command({ return this.session.adbclient.jdwp_command({
ths: this, ths: this,
extra: extra, extra: x.extra,
cmd: this.JDWP.Commands.suspendthread(threadid), cmd: this.JDWP.Commands.suspendthread(x.threadid),
}); });
}) })
.then((res,extra) => extra); .then((res,extra) => extra);
@@ -508,12 +510,13 @@ Debugger.prototype = {
}, },
resumethread: function (threadid, extra) { resumethread: function (threadid, extra) {
return this.ensureconnected(extra) return this.ensureconnected({threadid,extra})
.then(function (extra) { .then(function (x) {
this.session.threadsuspends[x.threadid] = (this.session.threadsuspends[x.threadid]|0) - 1;
return this.session.adbclient.jdwp_command({ return this.session.adbclient.jdwp_command({
ths: this, ths: this,
extra: extra, extra: x.extra,
cmd: this.JDWP.Commands.resumethread(threadid), cmd: this.JDWP.Commands.resumethread(x.threadid),
}); });
}) })
.then((res,extra) => extra); .then((res,extra) => extra);
@@ -1022,11 +1025,35 @@ Debugger.prototype = {
return o.def; return o.def;
}) })
.then((typeinfo, method, x) => { .then((typeinfo, method, x) => {
x.typeinfo = typeinfo;
x.method = method;
// in order to invoke the method, we must undo any manual suspends of the specified thread
// (and then resuspend after)
var def = $.Deferred().resolveWith(this,[null,x]);
for (var i=0; i < this.session.threadsuspends[x.threadid]|0; i++) {
def = def.then((res,x) => this.session.adbclient.jdwp_command({
ths: this, extra:x, cmd: this.JDWP.Commands.resumethread(x.threadid),
}));
}
return def;
})
.then((res,x) => {
return this.session.adbclient.jdwp_command({ return this.session.adbclient.jdwp_command({
ths: this, ths: this,
extra: x, extra: x,
cmd: this.JDWP.Commands.InvokeMethod(x.objectid, x.threadid, typeinfo.info.typeid, method.methodid, x.args), cmd: this.JDWP.Commands.InvokeMethod(x.objectid, x.threadid, x.typeinfo.info.typeid, x.method.methodid, x.args),
}); })
})
.then((res, x) => {
// save the result and re-suspend the thread
x.res = res;
var def = $.Deferred().resolveWith(this,[null,x]);
for (var i=0; i < this.session.threadsuspends[x.threadid]|0; i++) {
def = def.then((res,x) => this.session.adbclient.jdwp_command({
ths: this, extra:x, cmd: this.JDWP.Commands.suspendthread(x.threadid),
}));
}
return def.then((res,x) => $.Deferred().resolveWith(this, [x.res, x]));
}) })
.then((res, x) => { .then((res, x) => {
if (/^0+$/.test(res.exception)) if (/^0+$/.test(res.exception))
@@ -1636,7 +1663,7 @@ Debugger.prototype = {
}, },
fn: function (e) { fn: function (e) {
// each exception hit contributes a global suspend // each exception hit contributes a global suspend
x.dbgr.session.suspendcount++; e.data.dbgr.session.suspendcount++;
// if this exception break occurred during a step request, we must manually clear the event // if this exception break occurred during a step request, we must manually clear the event
// or the (device-side) debugger will crash on next step // or the (device-side) debugger will crash on next step
this._clearLastStepRequest(e.event.threadid, e).then(e => { this._clearLastStepRequest(e.event.threadid, e).then(e => {