에피소드
조각 모음 도구 #170 - 디버거 - JavaScript 스크립팅
조각 모음 도구의이 에피소드에서, 앤드류 리차즈는 Windows용 디버깅 도구 팀에서 앤디 루스와 빌 메스머에게 이야기. WDK 및 SDK 빌드 14951 이상에서 사용할 수 있는 WinDbg의 새로운 JavaScript 확장성 및 스크립팅 기능에 대해 설명합니다.
- 블로그- https://blogs.msdn.microsoft.com/windbg/
- 메일 주소- windbgfb@microsoft.com
Bill은 이전에 이러한 에피소드에서 디버거 개체 모델을 활용했습니다.
타임라인:
[00:00] 시작 및 소개
[00:24] 새 SDK 삭제
[00:29] JavaScript의 이유
[02:07] 새 명령
[03:50] Visual Studio Code
[04:00] 예제 - 헬로 월드
[07:15] 디버거 기본 네임스페이스
[09:07] 예제 - 모든 스레드 인쇄
[10:26] 예제 - 조건부 중단점
[18:13] 'g' vs. 'gc' – Andrew가 옳았다! 'gc'는 시작된 것과 동일한 방식으로 실행을 다시 시작합니다. 따라서 'p'를 누르고 'gc'가 있는 조건부 중단점에 도달하면 'gc'가 초기 'p'만 완료됩니다.
[20:40] 예제 - 고유 스택
[34:40] 예제 - 더하기
질문/의견? defragtools@microsoft.com으로 메일을 보내세요.
JavaScript MSDN 문서:
고유 스택 예제(오른쪽)
"use strict";
클래스 __stackEntry { constructor(frameString) { this.threads = []; this.frameString = frameString; this.children = new Map(); }
display(indent)
{
for (var child of this.children.values())
{
host.diagnostics.debugLog(indent, child.frameString, " [Threads In Branch: ");
for (var thread of child.threads)
{
host.diagnostics.debugLog(thread.Id, " ");
}
host.diagnostics.debugLog("]\n");
child.display(indent + " ");
}
}
}
클래스 __stackMap { constructor(process) { this.__process = process; this.__root = new __stackEntry(""); this.build(); }
build()
{
for (var thread of this.__process.Threads)
{
var current = this.__root;
var frameNum = 0;
var frameCount = thread.Stack.Frames.Count();
for (var frameNum = frameCount - 1; frameNum >= 0; --frameNum) {
var frame = thread.Stack.Frames[frameNum];
var frameString = frame.toString();
if (current.children.has(frameString)) {
current = current.children.get(frameString);
current.threads.push(thread);
}
else {
var newEntry = new __stackEntry(frameString);
current.children.set(frameString, newEntry);
current = newEntry;
current.threads.push(thread);
}
}
}
}
findEntry(thread)
{
var current = this.__root;
var frameCount = thread.Stack.Frames.Count();
for (var frameNum = frameCount - 1; frameNum >= 0; --frameNum)
{
var frame = thread.Stack.Frames[frameNum];
var frameString = frame.toString();
if (!current.children.has(frameString))
{
return null;
}
current = current.children.get(frameString);
}
return current;
}
display()
{
this.__root.display("");
}
}
클래스 __threadSameStacks { constructor(thread) { this.__thread = thread; }
getDimensionality()
{
return 1;
}
getValueAt(idx)
{
for (var idxVal of this)
{
var tid = idxVal[Symbol.indicies][0];
if (idxVal[Symbol.indicies][0] == idx && tid != this.__thread.Id)
{
return idxVal.value;
}
}
return undefined;
}
*[Symbol.iterator]()
{
var context = this.__thread.hostContext;
var session = host.namespace.Debugger.Sessions.getValueAt(context);
var process = session.Processes.getValueAt(context);
var map = new __stackMap(process);
var entry = map.findEntry(this.__thread);
if (entry != null)
{
for (var sharingThread of entry.threads)
{
if (sharingThread.Id != this.__thread.Id)
{
yield new host.indexedValue(sharingThread, [sharingThread.Id]);
}
}
}
}
}
class __threadExtension { get IdenticalStacks() { return new __threadSameStacks(this); } }
function invokeScript() { var map = new __stackMap(host.currentProcess); map.display(); }
function initializeScript() { return [new host.namedModelParent(__threadExtension, "Debugger.Models.Thread")]; }
조각 모음 도구의이 에피소드에서, 앤드류 리차즈는 Windows용 디버깅 도구 팀에서 앤디 루스와 빌 메스머에게 이야기. WDK 및 SDK 빌드 14951 이상에서 사용할 수 있는 WinDbg의 새로운 JavaScript 확장성 및 스크립팅 기능에 대해 설명합니다.
- 블로그- https://blogs.msdn.microsoft.com/windbg/
- 메일 주소- windbgfb@microsoft.com
Bill은 이전에 이러한 에피소드에서 디버거 개체 모델을 활용했습니다.
타임라인:
[00:00] 시작 및 소개
[00:24] 새 SDK 삭제
[00:29] JavaScript의 이유
[02:07] 새 명령
[03:50] Visual Studio Code
[04:00] 예제 - 헬로 월드
[07:15] 디버거 기본 네임스페이스
[09:07] 예제 - 모든 스레드 인쇄
[10:26] 예제 - 조건부 중단점
[18:13] 'g' vs. 'gc' – Andrew가 옳았다! 'gc'는 시작된 것과 동일한 방식으로 실행을 다시 시작합니다. 따라서 'p'를 누르고 'gc'가 있는 조건부 중단점에 도달하면 'gc'가 초기 'p'만 완료됩니다.
[20:40] 예제 - 고유 스택
[34:40] 예제 - 더하기
질문/의견? defragtools@microsoft.com으로 메일을 보내세요.
JavaScript MSDN 문서:
고유 스택 예제(오른쪽)
"use strict";
클래스 __stackEntry { constructor(frameString) { this.threads = []; this.frameString = frameString; this.children = new Map(); }
display(indent)
{
for (var child of this.children.values())
{
host.diagnostics.debugLog(indent, child.frameString, " [Threads In Branch: ");
for (var thread of child.threads)
{
host.diagnostics.debugLog(thread.Id, " ");
}
host.diagnostics.debugLog("]\n");
child.display(indent + " ");
}
}
}
클래스 __stackMap { constructor(process) { this.__process = process; this.__root = new __stackEntry(""); this.build(); }
build()
{
for (var thread of this.__process.Threads)
{
var current = this.__root;
var frameNum = 0;
var frameCount = thread.Stack.Frames.Count();
for (var frameNum = frameCount - 1; frameNum >= 0; --frameNum) {
var frame = thread.Stack.Frames[frameNum];
var frameString = frame.toString();
if (current.children.has(frameString)) {
current = current.children.get(frameString);
current.threads.push(thread);
}
else {
var newEntry = new __stackEntry(frameString);
current.children.set(frameString, newEntry);
current = newEntry;
current.threads.push(thread);
}
}
}
}
findEntry(thread)
{
var current = this.__root;
var frameCount = thread.Stack.Frames.Count();
for (var frameNum = frameCount - 1; frameNum >= 0; --frameNum)
{
var frame = thread.Stack.Frames[frameNum];
var frameString = frame.toString();
if (!current.children.has(frameString))
{
return null;
}
current = current.children.get(frameString);
}
return current;
}
display()
{
this.__root.display("");
}
}
클래스 __threadSameStacks { constructor(thread) { this.__thread = thread; }
getDimensionality()
{
return 1;
}
getValueAt(idx)
{
for (var idxVal of this)
{
var tid = idxVal[Symbol.indicies][0];
if (idxVal[Symbol.indicies][0] == idx && tid != this.__thread.Id)
{
return idxVal.value;
}
}
return undefined;
}
*[Symbol.iterator]()
{
var context = this.__thread.hostContext;
var session = host.namespace.Debugger.Sessions.getValueAt(context);
var process = session.Processes.getValueAt(context);
var map = new __stackMap(process);
var entry = map.findEntry(this.__thread);
if (entry != null)
{
for (var sharingThread of entry.threads)
{
if (sharingThread.Id != this.__thread.Id)
{
yield new host.indexedValue(sharingThread, [sharingThread.Id]);
}
}
}
}
}
class __threadExtension { get IdenticalStacks() { return new __threadSameStacks(this); } }
function invokeScript() { var map = new __stackMap(host.currentProcess); map.display(); }
function initializeScript() { return [new host.namedModelParent(__threadExtension, "Debugger.Models.Thread")]; }
의견이 있으신가요? 여기에서 문제를 제출합니다.