Skip to content

Support global lookup of symbols within scopes (namespaces, outer classes, etc.) on Windows #205

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 18, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions extensions/dbgobject/core/dbgobject.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,12 +122,12 @@ Loader.OnLoad(function() {
{name:"moduleName", type:"string", description:"The name of the module containing the symbol."},
{name:"symbol", type:"string", description:"The global symbol to lookup."},
{name: "typeName", type:"string", description: "(optional) The type name of the symbol to look up."},
{name: "scope", type:"string", description: "(optional) The scope of the symbol to look up (namespace, outer class, etc.). Required on some platforms."}
{name: "scopes", type:"array of strings", description: "(optional) Array of scopes of the symbol to look up (namespace, outer class, etc.). Order: [outermost scope, ..., innermost scope]."}
]
}
DbgObject.global = function(moduleName, symbol, typeName, scope) {
DbgObject.global = function(moduleName, symbol, typeName, scopes) {
return new PromisedDbgObject(
moduleBasedLookup(moduleName, JsDbgPromise.LookupGlobalSymbol, symbol, typeName, scope)
moduleBasedLookup(moduleName, JsDbgPromise.LookupGlobalSymbol, symbol, typeName, scopes)
.then(function(result) {
return DbgObject.create(DbgObjectType(result.module, result.type), result.pointer);
})
Expand Down
12 changes: 6 additions & 6 deletions extensions/jsdbg/core/jsdbg.js
Original file line number Diff line number Diff line change
Expand Up @@ -446,18 +446,18 @@ Loader.OnLoad(function () {
{name:"module", type:"string", description:"The module containing the symbol."},
{name:"symbol", type:"string", description:"The symbol to evaluate."},
{name:"typeName", type:"string", description: "The type name of the symbol to look up."},
{name:"scope", type:"string", description: "The scope of the symbol to look up (namespace, outer class, etc.). Required on some platforms."},
{name: "scopes", type:"array of strings", description: "(optional) Array of scopes of the symbol to look up (namespace, outer class, etc.). Order: [outermost scope, ..., innermost scope]."},
{name:"callback", type:"function(object)", description:"A callback that is called when the operation succeeds or fails."}
]
},
LookupGlobalSymbol: function(module, symbol, typeName, scope, callback) {
LookupGlobalSymbol: function(module, symbol, typeName, scopes, callback) {
var typenameStr = "";
if (typeName)
typenameStr = "&typeName=" + esc(typeName);
var scopeStr = "";
if (scope)
scopeStr = "&scope=" + esc(scope);
JsDbgTransport.JsonRequest("/jsdbg-server/global?module=" + esc(module) + "&symbol=" + esc(symbol) + typenameStr + scopeStr, callback, JsDbgTransport.CacheType.Cached);
var scopesStr = "";
if (scopes)
scopesStr = "&scopes=" + esc(scopes);
JsDbgTransport.JsonRequest("/jsdbg-server/global?module=" + esc(module) + "&symbol=" + esc(symbol) + typenameStr + scopesStr, callback, JsDbgTransport.CacheType.Cached);
},

_help_GetCallStack: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -773,7 +773,11 @@ Loader.OnLoad(function() {
description: "Returns (a promise to) a collection of documents for all web frames in the current renderer process."
},
GetDocuments: () => {
return DbgObject.global(Chromium.RendererProcessSyntheticModuleName, "g_frame_map", undefined, "content::(anonymous namespace)")
return DbgObject.global(Chromium.RendererProcessSyntheticModuleName, "g_frame_map", undefined, ["content", "anonymous namespace"])
.then(null, () => {
// Global symbol lookup failed; try without scopes (needed for older versions of Chromium on Windows)
return DbgObject.global(Chromium.RendererProcessSyntheticModuleName, "g_frame_map");
})
.then((frameMap) => Promise.map(frameMap.F("Object").array("Keys"), (webFramePointer) => webFramePointer.deref()))
.then((webFrames) => {
// Put the main frame (frame with a null parent) at the front of the array.
Expand Down
2 changes: 1 addition & 1 deletion server/JsDbg.Core/IDebugger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ public interface IDebugger {
Task<IEnumerable<SConstantResult>> LookupConstants(string module, string type, ulong constantValue);
Task<SConstantResult> LookupConstant(string module, string type, string constantName);
Task<SFieldResult> LookupField(string module, string typename, string fieldName);
Task<SSymbolResult> LookupGlobalSymbol(string module, string symbol, string typeName, string scope);
Task<SSymbolResult> LookupGlobalSymbol(string module, string symbol, string typeName, string[] scopes);
Task<SModule> GetModuleForName(string module);
Task<IEnumerable<SStackFrame>> GetCallStack(int frameCount);
Task<IEnumerable<SNamedSymbol>> GetSymbolsInStackFrame(ulong instructionAddress, ulong stackAddress, ulong frameAddress);
Expand Down
4 changes: 2 additions & 2 deletions server/JsDbg.Core/WebServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -774,15 +774,15 @@ private async void ServeGlobalSymbol(NameValueCollection query, Action<string> r
string module = query["module"];
string symbol = query["symbol"];
string typeName = query["typeName"];
string scope = query["scope"];
string scopes = query["scopes"];

if (module == null || symbol == null) {
fail();
return;
}
string responseString;
try {
SSymbolResult result = await this.debugger.LookupGlobalSymbol(module, symbol, typeName, scope);
SSymbolResult result = await this.debugger.LookupGlobalSymbol(module, symbol, typeName, scopes != null ? scopes.Split(',') : null);
responseString = String.Format("{{ \"pointer\": {0}, \"module\": \"{1}\", \"type\": \"{2}\" }}", result.Pointer, result.Module, result.Type);
} catch (DebuggerException ex) {
responseString = ex.JSONError;
Expand Down
23 changes: 18 additions & 5 deletions server/JsDbg.Stdio/StdioDebugger.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Threading.Tasks;
using JsDbg.Core;

Expand Down Expand Up @@ -240,14 +241,11 @@ public async Task<SFieldResult> LookupField(string module, string typename, stri
return field;
}

public async Task<SSymbolResult> LookupGlobalSymbol(string module, string symbol, string typename, string scope) {
public async Task<SSymbolResult> LookupGlobalSymbol(string module, string symbol, string typename, string[] scopes) {
NotifyDebuggerMessage(String.Format("Looking up value of global {0}...", symbol));

// For GDB, we use scope instead of typename to disambiguate globals.
string symbolName = "";
if (!String.IsNullOrEmpty(scope))
symbolName = scope + "::";
symbolName += symbol;
string symbolName = GetScopePrefix(scopes) + symbol;
string pythonResult = await this.QueryDebuggerPython(String.Format("LookupGlobalSymbol(\"{0}\",\"{1}\")", module, symbolName));
// '{%s#%d}' % (self.type, self.pointer)

Expand All @@ -268,6 +266,21 @@ public async Task<SSymbolResult> LookupGlobalSymbol(string module, string symbol
return result;
}

private string GetScopePrefix(string[] scopes) {
StringBuilder resultBuilder = new StringBuilder();
if (scopes != null) {
foreach (String scope in scopes) {
if (scope.Equals("anonymous namespace")) {
resultBuilder.Append('(').Append(scope).Append(')');
} else {
resultBuilder.Append(scope);
}
resultBuilder.Append("::");
}
}
return resultBuilder.ToString();
}

public async Task<SModule> GetModuleForName(string module) {
string pythonResult = await this.QueryDebuggerPython(String.Format("GetModuleForName(\"{0}\")", module));
if (pythonResult == "None")
Expand Down
21 changes: 18 additions & 3 deletions server/JsDbg.Windows/DiaDebugger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Dia2Lib;
using JsDbg.Core;
Expand Down Expand Up @@ -303,9 +304,8 @@ public async Task<uint> LookupTypeSize(string module, string typename) {
return (await this.LoadType(module, typename)).Size;
}

public async Task<SSymbolResult> LookupGlobalSymbol(string moduleName, string symbolName, string typeName, string scope) {
// The scope is not needed to lookup global symbols with DIA.

public async Task<SSymbolResult> LookupGlobalSymbol(string moduleName, string symbolName, string typeName, string[] scopes) {
symbolName = GetScopePrefix(scopes) + symbolName;
Dia2Lib.IDiaSession session = await this.debuggerEngine.DiaLoader.LoadDiaSession(moduleName);
if (session != null) {
// We have a DIA session, use that.
Expand Down Expand Up @@ -337,6 +337,21 @@ public async Task<SSymbolResult> LookupGlobalSymbol(string moduleName, string sy
return await this.debuggerEngine.LookupGlobalSymbol(moduleName, symbolName, typeName);
}
}

private string GetScopePrefix(string[] scopes) {
StringBuilder resultBuilder = new StringBuilder();
if (scopes != null) {
foreach (String scope in scopes) {
if (scope.Equals("anonymous namespace")) {
resultBuilder.Append('`').Append(scope).Append('\'');
} else {
resultBuilder.Append(scope);
}
resultBuilder.Append("::");
}
}
return resultBuilder.ToString();
}

public Task<SModule> GetModuleForName(string module) {
return this.debuggerEngine.GetModuleForName(module);
Expand Down