Skip to content

Commit 48c028f

Browse files
committed
Support for configuration file with additional script search directories
1 parent fad529b commit 48c028f

File tree

4 files changed

+132
-12
lines changed

4 files changed

+132
-12
lines changed

LuaDkmDebugger/source.extension.vsixmanifest

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<PackageManifest Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2011" xmlns:d="http://schemas.microsoft.com/developer/vsx-schema-design/2011">
33
<Metadata>
4-
<Identity Id="LuaDkmDebugger.e3e2ef04-27c9-46a6-ad45-79bd29067eb6" Version="0.2.3" Language="en-US" Publisher="WheretIB" />
4+
<Identity Id="LuaDkmDebugger.e3e2ef04-27c9-46a6-ad45-79bd29067eb6" Version="0.2.4" Language="en-US" Publisher="WheretIB" />
55
<DisplayName>C++ debugger extensions for Lua</DisplayName>
66
<Description xml:space="preserve">This Visual Studio extension enables limited support for inspection of Lua (Version 5.3) state in C++ applications during debug.</Description>
77
<License>license.txt</License>

LuaDkmDebuggerComponent/LocalComponent.cs

Lines changed: 110 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,17 @@
77
using System;
88
using System.Collections.Generic;
99
using System.Diagnostics;
10+
using System.IO;
1011
using System.Linq;
12+
using System.Web.Script.Serialization;
1113

1214
namespace LuaDkmDebuggerComponent
1315
{
16+
internal class LuaDebugConfiguration
17+
{
18+
public List<string> ScriptPaths = new List<string>();
19+
}
20+
1421
internal class LuaLocalProcessData : DkmDataItem
1522
{
1623
public DkmCustomRuntimeInstance runtimeInstance = null;
@@ -21,6 +28,8 @@ internal class LuaLocalProcessData : DkmDataItem
2128
public bool workingDirectoryRequested = false;
2229
public string workingDirectory = null;
2330

31+
public LuaDebugConfiguration configuration;
32+
2433
// Stack walk data for multiple switches between Lua and C++
2534
public bool seenLuaFrame = false;
2635
public int skipFrames = 0; // How many Lua frames to skip
@@ -113,6 +122,45 @@ internal string TryEvaluateStringExpression(string expression, DkmStackContext s
113122
return ExecuteExpression(expression + ",sb", stackContext, input, false, out _);
114123
}
115124

125+
internal void LoadConfigurationFile(DkmProcess process, LuaLocalProcessData processData)
126+
{
127+
// Check if already loaded
128+
if (processData.configuration != null)
129+
return;
130+
131+
bool TryLoad(string path)
132+
{
133+
if (File.Exists(path))
134+
{
135+
var serializer = new JavaScriptSerializer();
136+
137+
try
138+
{
139+
processData.configuration = serializer.Deserialize<LuaDebugConfiguration>(File.ReadAllText(path));
140+
141+
return processData.configuration != null;
142+
}
143+
catch (Exception e)
144+
{
145+
Debug.WriteLine("Failed to load configuration: " + e.Message);
146+
}
147+
}
148+
149+
return false;
150+
}
151+
152+
string pathA = $"{Path.GetDirectoryName(process.Path)}\\";
153+
154+
if (TryLoad(pathA + "lua_dkm_debug.json"))
155+
return;
156+
157+
if (processData.workingDirectory == null)
158+
return;
159+
160+
if (TryLoad($"{processData.workingDirectory}\\" + "lua_dkm_debug.json"))
161+
return;
162+
}
163+
116164
DkmStackWalkFrame[] IDkmCallStackFilter.FilterNextFrame(DkmStackContext stackContext, DkmStackWalkFrame input)
117165
{
118166
// null input frame indicates the end of the call stack
@@ -168,6 +216,7 @@ DkmStackWalkFrame[] IDkmCallStackFilter.FilterNextFrame(DkmStackContext stackCon
168216
if (processData.scratchMemory == 0)
169217
return new DkmStackWalkFrame[1] { input };
170218

219+
// Find out the current process working directory (Lua script files will be resolved from that location)
171220
if (processData.workingDirectory == null && !processData.workingDirectoryRequested)
172221
{
173222
processData.workingDirectoryRequested = true;
@@ -184,6 +233,8 @@ DkmStackWalkFrame[] IDkmCallStackFilter.FilterNextFrame(DkmStackContext stackCon
184233
}
185234
}
186235

236+
LoadConfigurationFile(process, processData);
237+
187238
// TODO: Replace with enumerations from Bytecode.cs
188239
const int luaBaseTypeMask = 0xf;
189240
const int luaExtendedTypeMask = 0x3f;
@@ -436,24 +487,74 @@ DkmSourcePosition IDkmSymbolQuery.GetSourcePosition(DkmInstructionSymbol instruc
436487

437488
frameData.ReadFrom(instructionSymbol.AdditionalData.ToArray());
438489

490+
string CheckConfigPaths(string winSourcePath)
491+
{
492+
if (processData.configuration != null && processData.configuration.ScriptPaths != null)
493+
{
494+
foreach (var path in processData.configuration.ScriptPaths)
495+
{
496+
var finalPath = path.Replace('/', '\\');
497+
498+
if (!Path.IsPathRooted(finalPath))
499+
{
500+
if (processData.workingDirectory != null)
501+
{
502+
string test = Path.GetFullPath(Path.Combine(processData.workingDirectory, finalPath)) + winSourcePath.Substring(1);
503+
504+
if (File.Exists(test))
505+
return test;
506+
}
507+
508+
{
509+
string test = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(process.Path), finalPath)) + winSourcePath.Substring(1);
510+
511+
if (File.Exists(test))
512+
return test;
513+
}
514+
}
515+
else
516+
{
517+
string test = finalPath + winSourcePath.Substring(1);
518+
519+
if (File.Exists(test))
520+
return test;
521+
}
522+
}
523+
}
524+
525+
return null;
526+
}
527+
439528
string filePath;
440529

441530
if (frameData.source.StartsWith("@"))
442531
{
443532
string winSourcePath = frameData.source.Replace('/', '\\');
444533

445-
if (processData.workingDirectory != null)
446-
filePath = $"{processData.workingDirectory}\\{winSourcePath.Substring(1)}";
447-
else
448-
filePath = winSourcePath.Substring(1);
534+
filePath = CheckConfigPaths(winSourcePath);
535+
536+
if (filePath == null)
537+
{
538+
if (processData.workingDirectory != null)
539+
filePath = $"{processData.workingDirectory}\\{winSourcePath.Substring(1)}";
540+
else
541+
filePath = winSourcePath.Substring(1);
542+
}
449543
}
450544
else
451545
{
452-
// TODO: how can we display internal scripts in the debugger?
453-
if (processData.workingDirectory != null)
454-
filePath = $"{processData.workingDirectory}\\internal.lua";
455-
else
456-
filePath = "internal.lua";
546+
string winSourcePath = frameData.source.Replace('/', '\\');
547+
548+
filePath = CheckConfigPaths(winSourcePath);
549+
550+
if (filePath == null)
551+
{
552+
// TODO: how can we display internal scripts in the debugger?
553+
if (processData.workingDirectory != null)
554+
filePath = $"{processData.workingDirectory}\\internal.lua";
555+
else
556+
filePath = "internal.lua";
557+
}
457558
}
458559

459560
startOfLine = true;

LuaDkmDebuggerComponent/LuaDkmDebuggerComponent.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
<ItemGroup>
3434
<Reference Include="System" />
3535
<Reference Include="System.Core" />
36+
<Reference Include="System.Web.Extensions" />
3637
<Reference Include="System.Xml.Linq" />
3738
<Reference Include="System.Data.DataSetExtensions" />
3839
<Reference Include="Microsoft.CSharp" />

README.md

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,24 @@ This Visual Studio extension enables limited support for inspection of Lua (Vers
1414

1515
![Example debug session](https://github.com/WheretIB/LuaDkmDebugger/blob/master/resource/front_image.png?raw=true)
1616

17-
## Known Issues:
17+
## Additional configuration
18+
19+
In the default configuration, debugger searches for script files in current working directory and application executable directory.
20+
21+
Application may provide Lua with script file paths that do not match the file system. To help the debugger find your script files in this scenario, additional script search paths can be provided using an optional configuration file.
22+
23+
`lua_dkm_debug.json` file can be placed in application working directory or near the executable file.
24+
25+
Add `ScriptPaths` key with an array of additional search paths.
26+
27+
```
28+
{
29+
"ScriptPaths": [
30+
"../",
31+
"../scripts/base/"
32+
]
33+
}
34+
```
35+
36+
## Known Issues:
1837
* This extension will always add Lua module to the application (can be seen in 'Modules' section of the debugger) even when debugging applications with no Lua code (check notes in RemoteComponent.cs)
19-
* Lua source files are located based on the process working directory, additional configuration options are planned in the future

0 commit comments

Comments
 (0)