Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
73b7f479
V
vscode
项目概览
xxadev
/
vscode
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
V
vscode
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
73b7f479
编写于
9月 05, 2018
作者:
A
Andre Weinand
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
debt: clean up DA error handling; fixes #57810
上级
a1ac197b
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
262 addition
and
230 deletion
+262
-230
src/vs/workbench/parts/debug/common/debug.ts
src/vs/workbench/parts/debug/common/debug.ts
+1
-1
src/vs/workbench/parts/debug/electron-browser/debugService.ts
...vs/workbench/parts/debug/electron-browser/debugService.ts
+30
-8
src/vs/workbench/parts/debug/electron-browser/debugSession.ts
...vs/workbench/parts/debug/electron-browser/debugSession.ts
+155
-144
src/vs/workbench/parts/debug/electron-browser/rawDebugSession.ts
...workbench/parts/debug/electron-browser/rawDebugSession.ts
+75
-76
src/vs/workbench/parts/debug/test/common/mockDebug.ts
src/vs/workbench/parts/debug/test/common/mockDebug.ts
+1
-1
未找到文件。
src/vs/workbench/parts/debug/common/debug.ts
浏览文件 @
73b7f479
...
...
@@ -167,7 +167,7 @@ export interface ISession extends ITreeElement, IDisposable {
/**
* Allows to register on DA events.
*/
onDidExitAdapter
:
Event
<
void
>
;
onDidExitAdapter
:
Event
<
Error
>
;
}
export
interface
IThread
extends
ITreeElement
{
...
...
src/vs/workbench/parts/debug/electron-browser/debugService.ts
浏览文件 @
73b7f479
...
...
@@ -400,6 +400,10 @@ export class DebugService implements IDebugService {
});
}
private
isExtensionHostDebugging
(
config
:
IConfig
)
{
return
equalsIgnoreCase
(
config
.
type
,
'
extensionhost
'
);
}
private
attachExtensionHost
(
session
:
Session
,
port
:
number
):
TPromise
<
void
>
{
session
.
configuration
.
request
=
'
attach
'
;
...
...
@@ -418,18 +422,25 @@ export class DebugService implements IDebugService {
const
session
=
this
.
instantiationService
.
createInstance
(
Session
,
configuration
,
root
,
this
.
model
);
this
.
allSessions
.
set
(
session
.
getId
(),
session
);
// register listeners as the very first thing!
this
.
registerSessionListeners
(
session
);
// since the Session is now properly registered under its ID and hooked, we can announce it
// this event doesn't go to extensions
this
.
_onWillNewSession
.
fire
(
session
);
const
resolved
=
configuration
.
resolved
;
resolved
.
__sessionId
=
session
.
getId
();
const
dbgr
=
this
.
configurationManager
.
getDebugger
(
resolved
.
type
);
return
session
.
initialize
(
dbgr
).
then
(()
=>
{
this
.
registerSessionListeners
(
session
);
const
raw
=
<
RawDebugSession
>
session
.
raw
;
// pass the sessionID for EH debugging
if
(
this
.
isExtensionHostDebugging
(
resolved
))
{
resolved
.
__sessionId
=
session
.
getId
();
}
return
(
resolved
.
request
===
'
attach
'
?
raw
.
attach
(
resolved
)
:
raw
.
launch
(
resolved
)).
then
(
result
=>
{
if
(
raw
.
disconnected
)
{
...
...
@@ -438,6 +449,7 @@ export class DebugService implements IDebugService {
this
.
focusStackFrame
(
undefined
,
undefined
,
session
);
// since the initialized response has arrived announce the new Session (including extensions)
this
.
_onDidNewSession
.
fire
(
session
);
const
internalConsoleOptions
=
resolved
.
internalConsoleOptions
||
this
.
configurationService
.
getValue
<
IDebugConfiguration
>
(
'
debug
'
).
internalConsoleOptions
;
...
...
@@ -460,6 +472,7 @@ export class DebugService implements IDebugService {
return
this
.
telemetryDebugSessionStart
(
root
,
resolved
.
type
,
dbgr
.
extensionDescription
);
}).
then
(()
=>
session
,
(
error
:
Error
|
string
)
=>
{
if
(
session
)
{
session
.
dispose
();
}
...
...
@@ -483,13 +496,18 @@ export class DebugService implements IDebugService {
}
return
undefined
;
});
}).
then
(
undefined
,
err
=>
{
}).
then
(
undefined
,
error
=>
{
if
(
session
)
{
session
.
dispose
();
}
return
TPromise
.
wrapError
(
err
);
if
(
errors
.
isPromiseCanceledError
(
error
))
{
// Do not show 'canceled' error messages to the user #7906
return
TPromise
.
as
(
null
);
}
return
TPromise
.
wrapError
(
error
);
});
}
...
...
@@ -502,10 +520,14 @@ export class DebugService implements IDebugService {
this
.
onStateChange
();
}));
this
.
toDispose
.
push
(
session
.
onDidExitAdapter
(()
=>
{
this
.
toDispose
.
push
(
session
.
onDidExitAdapter
(
err
=>
{
if
(
err
)
{
this
.
notificationService
.
error
(
nls
.
localize
(
'
debugAdapterCrash
'
,
"
Debug adapter process has terminated unexpectedly ({0})
"
,
err
.
message
||
err
.
toString
()));
}
// 'Run without debugging' mode VSCode must terminate the extension host. More details: #3905
if
(
equalsIgnoreCase
(
session
.
configuration
.
type
,
'
extensionhost
'
)
&&
session
.
state
===
State
.
Running
&&
session
.
configuration
.
noDebug
)
{
if
(
this
.
isExtensionHostDebugging
(
session
.
configuration
)
&&
session
.
state
===
State
.
Running
&&
session
.
configuration
.
noDebug
)
{
this
.
broadcastService
.
broadcast
({
channel
:
EXTENSION_CLOSE_EXTHOST_BROADCAST_CHANNEL
,
payload
:
[
session
.
root
.
uri
.
toString
()]
...
...
@@ -553,7 +575,7 @@ export class DebugService implements IDebugService {
// Do not run preLaunch and postDebug tasks for automatic restarts
this
.
skipRunningTask
=
!!
restartData
;
if
(
equalsIgnoreCase
(
session
.
configuration
.
type
,
'
extensionHost
'
)
&&
session
.
root
)
{
if
(
this
.
isExtensionHostDebugging
(
session
.
configuration
)
&&
session
.
root
)
{
return
this
.
broadcastService
.
broadcast
({
channel
:
EXTENSION_RELOAD_BROADCAST_CHANNEL
,
payload
:
[
session
.
root
.
uri
.
toString
()]
...
...
src/vs/workbench/parts/debug/electron-browser/debugSession.ts
浏览文件 @
73b7f479
...
...
@@ -41,7 +41,7 @@ export class Session implements ISession {
private
readonly
_onDidLoadedSource
=
new
Emitter
<
LoadedSourceEvent
>
();
private
readonly
_onDidCustomEvent
=
new
Emitter
<
DebugProtocol
.
Event
>
();
private
readonly
_onDidChangeState
=
new
Emitter
<
State
>
();
private
readonly
_onDidExitAdapter
=
new
Emitter
<
void
>
();
private
readonly
_onDidExitAdapter
=
new
Emitter
<
Error
>
();
constructor
(
private
_configuration
:
{
resolved
:
IConfig
,
unresolved
:
IConfig
},
...
...
@@ -93,149 +93,25 @@ export class Session implements ISession {
return
this
.
_onDidChangeState
.
event
;
}
getSourceForUri
(
modelUri
:
uri
):
Source
{
return
this
.
sources
.
get
(
modelUri
.
toString
());
}
getSource
(
raw
:
DebugProtocol
.
Source
):
Source
{
let
source
=
new
Source
(
raw
,
this
.
getId
());
if
(
this
.
sources
.
has
(
source
.
uri
.
toString
()))
{
source
=
this
.
sources
.
get
(
source
.
uri
.
toString
());
source
.
raw
=
mixin
(
source
.
raw
,
raw
);
if
(
source
.
raw
&&
raw
)
{
// Always take the latest presentation hint from adapter #42139
source
.
raw
.
presentationHint
=
raw
.
presentationHint
;
}
}
else
{
this
.
sources
.
set
(
source
.
uri
.
toString
(),
source
);
}
return
source
;
}
getThread
(
threadId
:
number
):
Thread
{
return
this
.
threads
.
get
(
threadId
);
}
getAllThreads
():
IThread
[]
{
const
result
:
IThread
[]
=
[];
this
.
threads
.
forEach
(
t
=>
result
.
push
(
t
));
return
result
;
}
getLoadedSources
():
TPromise
<
Source
[]
>
{
return
this
.
_raw
.
loadedSources
({}).
then
(
response
=>
{
return
response
.
body
.
sources
.
map
(
src
=>
this
.
getSource
(
src
));
},
()
=>
{
return
[];
});
}
get
onDidLoadedSource
():
Event
<
LoadedSourceEvent
>
{
return
this
.
_onDidLoadedSource
.
event
;
}
get
onDidCustomEvent
():
Event
<
DebugProtocol
.
Event
>
{
return
this
.
_onDidCustomEvent
.
event
;
}
get
onDidExitAdapter
():
Event
<
void
>
{
get
onDidExitAdapter
():
Event
<
Error
>
{
return
this
.
_onDidExitAdapter
.
event
;
}
rawUpdate
(
data
:
IRawModelUpdate
):
void
{
if
(
data
.
thread
&&
!
this
.
threads
.
has
(
data
.
threadId
))
{
// A new thread came in, initialize it.
this
.
threads
.
set
(
data
.
threadId
,
new
Thread
(
this
,
data
.
thread
.
name
,
data
.
thread
.
id
));
}
else
if
(
data
.
thread
&&
data
.
thread
.
name
)
{
// Just the thread name got updated #18244
this
.
threads
.
get
(
data
.
threadId
).
name
=
data
.
thread
.
name
;
}
if
(
data
.
stoppedDetails
)
{
// Set the availability of the threads' callstacks depending on
// whether the thread is stopped or not
if
(
data
.
stoppedDetails
.
allThreadsStopped
)
{
this
.
threads
.
forEach
(
thread
=>
{
thread
.
stoppedDetails
=
thread
.
threadId
===
data
.
threadId
?
data
.
stoppedDetails
:
{
reason
:
undefined
};
thread
.
stopped
=
true
;
thread
.
clearCallStack
();
});
}
else
if
(
this
.
threads
.
has
(
data
.
threadId
))
{
// One thread is stopped, only update that thread.
const
thread
=
this
.
threads
.
get
(
data
.
threadId
);
thread
.
stoppedDetails
=
data
.
stoppedDetails
;
thread
.
clearCallStack
();
thread
.
stopped
=
true
;
}
}
}
clearThreads
(
removeThreads
:
boolean
,
reference
:
number
=
undefined
):
void
{
if
(
reference
!==
undefined
&&
reference
!==
null
)
{
if
(
this
.
threads
.
has
(
reference
))
{
const
thread
=
this
.
threads
.
get
(
reference
);
thread
.
clearCallStack
();
thread
.
stoppedDetails
=
undefined
;
thread
.
stopped
=
false
;
if
(
removeThreads
)
{
this
.
threads
.
delete
(
reference
);
}
}
}
else
{
this
.
threads
.
forEach
(
thread
=>
{
thread
.
clearCallStack
();
thread
.
stoppedDetails
=
undefined
;
thread
.
stopped
=
false
;
});
if
(
removeThreads
)
{
this
.
threads
.
clear
();
ExpressionContainer
.
allValues
.
clear
();
}
}
}
completions
(
frameId
:
number
,
text
:
string
,
position
:
Position
,
overwriteBefore
:
number
):
TPromise
<
ISuggestion
[]
>
{
if
(
!
this
.
_raw
.
capabilities
.
supportsCompletionsRequest
)
{
return
TPromise
.
as
([]);
}
return
this
.
_raw
.
completions
({
frameId
,
text
,
column
:
position
.
column
,
line
:
position
.
lineNumber
}).
then
(
response
=>
{
const
result
:
ISuggestion
[]
=
[];
if
(
response
&&
response
.
body
&&
response
.
body
.
targets
)
{
response
.
body
.
targets
.
forEach
(
item
=>
{
if
(
item
&&
item
.
label
)
{
result
.
push
({
label
:
item
.
label
,
insertText
:
item
.
text
||
item
.
label
,
type
:
item
.
type
,
filterText
:
item
.
start
&&
item
.
length
&&
text
.
substr
(
item
.
start
,
item
.
length
).
concat
(
item
.
label
),
overwriteBefore
:
item
.
length
||
overwriteBefore
});
}
});
}
return
result
;
},
()
=>
[]);
}
initialize
(
dbgr
:
Debugger
):
TPromise
<
void
>
{
if
(
this
.
_raw
)
{
//
I
f there was already a connection make sure to remove old listeners
this
.
dispose
();
//
i
f there was already a connection make sure to remove old listeners
this
.
dispose
();
// TODO: do not use dispose for this!
}
return
dbgr
.
getCustomTelemetryService
().
then
(
customTelemetryService
=>
{
this
.
_raw
=
this
.
instantiationService
.
createInstance
(
RawDebugSession
,
this
.
_configuration
.
resolved
.
debugServer
,
dbgr
,
customTelemetryService
,
this
.
root
);
this
.
registerListeners
();
return
this
.
_raw
.
initialize
({
...
...
@@ -249,7 +125,7 @@ export class Session implements ISession {
supportsVariablePaging
:
true
,
// #9537
supportsRunInTerminalRequest
:
true
,
// #10574
locale
:
platform
.
locale
}).
then
(
()
=>
{
}).
then
(
response
=>
{
this
.
model
.
addSession
(
this
);
this
.
state
=
State
.
Running
;
this
.
model
.
setExceptionBreakpoints
(
this
.
_raw
.
capabilities
.
exceptionBreakpointFilters
);
...
...
@@ -258,6 +134,7 @@ export class Session implements ISession {
}
private
registerListeners
():
void
{
this
.
rawListeners
.
push
(
this
.
_raw
.
onDidInitialize
(()
=>
{
aria
.
status
(
nls
.
localize
(
'
debuggingStarted
'
,
"
Debugging started.
"
));
const
sendConfigurationDone
=
()
=>
{
...
...
@@ -415,7 +292,152 @@ export class Session implements ISession {
this
.
_onDidCustomEvent
.
fire
(
event
);
}));
this
.
rawListeners
.
push
(
this
.
_raw
.
onDidExitAdapter
(()
=>
this
.
_onDidExitAdapter
.
fire
()));
this
.
rawListeners
.
push
(
this
.
_raw
.
onDidExitAdapter
(
error
=>
{
this
.
_onDidExitAdapter
.
fire
(
error
);
}));
}
dispose
():
void
{
dispose
(
this
.
rawListeners
);
this
.
model
.
clearThreads
(
this
.
getId
(),
true
);
this
.
model
.
removeSession
(
this
.
getId
());
this
.
fetchThreadsScheduler
=
undefined
;
if
(
this
.
_raw
&&
!
this
.
_raw
.
disconnected
)
{
this
.
_raw
.
disconnect
();
}
this
.
_raw
=
undefined
;
}
//---- sources
getSourceForUri
(
modelUri
:
uri
):
Source
{
return
this
.
sources
.
get
(
modelUri
.
toString
());
}
getSource
(
raw
:
DebugProtocol
.
Source
):
Source
{
let
source
=
new
Source
(
raw
,
this
.
getId
());
if
(
this
.
sources
.
has
(
source
.
uri
.
toString
()))
{
source
=
this
.
sources
.
get
(
source
.
uri
.
toString
());
source
.
raw
=
mixin
(
source
.
raw
,
raw
);
if
(
source
.
raw
&&
raw
)
{
// Always take the latest presentation hint from adapter #42139
source
.
raw
.
presentationHint
=
raw
.
presentationHint
;
}
}
else
{
this
.
sources
.
set
(
source
.
uri
.
toString
(),
source
);
}
return
source
;
}
getLoadedSources
():
TPromise
<
Source
[]
>
{
return
this
.
_raw
.
loadedSources
({}).
then
(
response
=>
{
return
response
.
body
.
sources
.
map
(
src
=>
this
.
getSource
(
src
));
},
()
=>
{
return
[];
});
}
get
onDidLoadedSource
():
Event
<
LoadedSourceEvent
>
{
return
this
.
_onDidLoadedSource
.
event
;
}
//---- completions
completions
(
frameId
:
number
,
text
:
string
,
position
:
Position
,
overwriteBefore
:
number
):
TPromise
<
ISuggestion
[]
>
{
if
(
!
this
.
_raw
.
capabilities
.
supportsCompletionsRequest
)
{
return
TPromise
.
as
([]);
}
return
this
.
_raw
.
completions
({
frameId
,
text
,
column
:
position
.
column
,
line
:
position
.
lineNumber
}).
then
(
response
=>
{
const
result
:
ISuggestion
[]
=
[];
if
(
response
&&
response
.
body
&&
response
.
body
.
targets
)
{
response
.
body
.
targets
.
forEach
(
item
=>
{
if
(
item
&&
item
.
label
)
{
result
.
push
({
label
:
item
.
label
,
insertText
:
item
.
text
||
item
.
label
,
type
:
item
.
type
,
filterText
:
item
.
start
&&
item
.
length
&&
text
.
substr
(
item
.
start
,
item
.
length
).
concat
(
item
.
label
),
overwriteBefore
:
item
.
length
||
overwriteBefore
});
}
});
}
return
result
;
},
()
=>
[]);
}
//---- threads
getThread
(
threadId
:
number
):
Thread
{
return
this
.
threads
.
get
(
threadId
);
}
getAllThreads
():
IThread
[]
{
const
result
:
IThread
[]
=
[];
this
.
threads
.
forEach
(
t
=>
result
.
push
(
t
));
return
result
;
}
clearThreads
(
removeThreads
:
boolean
,
reference
:
number
=
undefined
):
void
{
if
(
reference
!==
undefined
&&
reference
!==
null
)
{
if
(
this
.
threads
.
has
(
reference
))
{
const
thread
=
this
.
threads
.
get
(
reference
);
thread
.
clearCallStack
();
thread
.
stoppedDetails
=
undefined
;
thread
.
stopped
=
false
;
if
(
removeThreads
)
{
this
.
threads
.
delete
(
reference
);
}
}
}
else
{
this
.
threads
.
forEach
(
thread
=>
{
thread
.
clearCallStack
();
thread
.
stoppedDetails
=
undefined
;
thread
.
stopped
=
false
;
});
if
(
removeThreads
)
{
this
.
threads
.
clear
();
ExpressionContainer
.
allValues
.
clear
();
}
}
}
rawUpdate
(
data
:
IRawModelUpdate
):
void
{
if
(
data
.
thread
&&
!
this
.
threads
.
has
(
data
.
threadId
))
{
// A new thread came in, initialize it.
this
.
threads
.
set
(
data
.
threadId
,
new
Thread
(
this
,
data
.
thread
.
name
,
data
.
thread
.
id
));
}
else
if
(
data
.
thread
&&
data
.
thread
.
name
)
{
// Just the thread name got updated #18244
this
.
threads
.
get
(
data
.
threadId
).
name
=
data
.
thread
.
name
;
}
if
(
data
.
stoppedDetails
)
{
// Set the availability of the threads' callstacks depending on
// whether the thread is stopped or not
if
(
data
.
stoppedDetails
.
allThreadsStopped
)
{
this
.
threads
.
forEach
(
thread
=>
{
thread
.
stoppedDetails
=
thread
.
threadId
===
data
.
threadId
?
data
.
stoppedDetails
:
{
reason
:
undefined
};
thread
.
stopped
=
true
;
thread
.
clearCallStack
();
});
}
else
if
(
this
.
threads
.
has
(
data
.
threadId
))
{
// One thread is stopped, only update that thread.
const
thread
=
this
.
threads
.
get
(
data
.
threadId
);
thread
.
stoppedDetails
=
data
.
stoppedDetails
;
thread
.
clearCallStack
();
thread
.
stopped
=
true
;
}
}
}
private
fetchThreads
(
stoppedDetails
?:
IRawStoppedDetails
):
TPromise
<
any
>
{
...
...
@@ -432,15 +454,4 @@ export class Session implements ISession {
}
});
}
dispose
():
void
{
dispose
(
this
.
rawListeners
);
this
.
model
.
clearThreads
(
this
.
getId
(),
true
);
this
.
model
.
removeSession
(
this
.
getId
());
this
.
fetchThreadsScheduler
=
undefined
;
if
(
!
this
.
_raw
.
disconnected
)
{
this
.
_raw
.
disconnect
();
}
this
.
_raw
=
undefined
;
}
}
src/vs/workbench/parts/debug/electron-browser/rawDebugSession.ts
浏览文件 @
73b7f479
...
...
@@ -13,7 +13,6 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import
{
Debugger
}
from
'
vs/workbench/parts/debug/node/debugger
'
;
import
{
IOutputService
}
from
'
vs/workbench/parts/output/common/output
'
;
import
{
IWorkspaceFolder
}
from
'
vs/platform/workspace/common/workspace
'
;
import
{
INotificationService
}
from
'
vs/platform/notification/common/notification
'
;
import
{
formatPII
}
from
'
vs/workbench/parts/debug/common/debugUtils
'
;
import
{
SocketDebugAdapter
}
from
'
vs/workbench/parts/debug/node/debugAdapter
'
;
import
{
IRawSession
,
IDebugAdapter
}
from
'
vs/workbench/parts/debug/common/debug
'
;
...
...
@@ -26,7 +25,7 @@ export class RawDebugSession implements IRawSession {
public
disconnected
:
boolean
;
private
debugAdapter
:
IDebugAdapter
;
private
cachedInit
Serv
erP
:
TPromise
<
void
>
;
private
cachedInit
DebugAdapt
erP
:
TPromise
<
void
>
;
private
startTime
:
number
;
private
terminated
:
boolean
;
private
cancellationTokens
:
CancellationTokenSource
[];
...
...
@@ -48,14 +47,13 @@ export class RawDebugSession implements IRawSession {
private
readonly
_onDidEvent
:
Emitter
<
DebugProtocol
.
Event
>
;
// DA events
private
readonly
_onDidExitAdapter
:
Emitter
<
void
>
;
private
readonly
_onDidExitAdapter
:
Emitter
<
Error
>
;
constructor
(
private
debugServerPort
:
number
,
private
_debugger
:
Debugger
,
public
customTelemetryService
:
ITelemetryService
,
private
root
:
IWorkspaceFolder
,
@
INotificationService
private
notificationService
:
INotificationService
,
@
ITelemetryService
private
telemetryService
:
ITelemetryService
,
@
IOutputService
private
outputService
:
IOutputService
)
{
...
...
@@ -76,7 +74,7 @@ export class RawDebugSession implements IRawSession {
this
.
_onDidCustomEvent
=
new
Emitter
<
DebugProtocol
.
Event
>
();
this
.
_onDidEvent
=
new
Emitter
<
DebugProtocol
.
Event
>
();
this
.
_onDidExitAdapter
=
new
Emitter
<
void
>
();
this
.
_onDidExitAdapter
=
new
Emitter
<
Error
>
();
}
// DAP events
...
...
@@ -126,83 +124,81 @@ export class RawDebugSession implements IRawSession {
}
// DA event
public
get
onDidExitAdapter
():
Event
<
void
>
{
public
get
onDidExitAdapter
():
Event
<
Error
>
{
return
this
.
_onDidExitAdapter
.
event
;
}
private
initServ
er
():
TPromise
<
void
>
{
private
startAdapt
er
():
TPromise
<
void
>
{
if
(
this
.
cachedInitServerP
)
{
return
this
.
cachedInitServerP
;
}
const
startSessionP
=
this
.
startSession
();
this
.
cachedInitServerP
=
startSessionP
.
then
(()
=>
{
this
.
startTime
=
new
Date
().
getTime
();
},
err
=>
{
this
.
cachedInitServerP
=
null
;
return
TPromise
.
wrapError
(
err
);
});
if
(
!
this
.
cachedInitDebugAdapterP
)
{
return
this
.
cachedInitServerP
;
}
private
startSession
():
TPromise
<
void
>
{
const
startSessionP
=
this
.
_debugger
.
createDebugAdapter
(
this
.
root
,
this
.
outputService
,
this
.
debugServerPort
).
then
(
debugAdapter
=>
{
return
this
.
_debugger
.
createDebugAdapter
(
this
.
root
,
this
.
outputService
,
this
.
debugServerPort
).
then
(
debugAdapter
=>
{
this
.
debugAdapter
=
debugAdapter
;
this
.
debugAdapter
=
debugAdapter
;
this
.
debugAdapter
.
onError
(
err
=>
this
.
onDebugAdapterError
(
err
));
this
.
debugAdapter
.
onEvent
(
event
=>
this
.
onDapEvent
(
event
));
this
.
debugAdapter
.
onRequest
(
request
=>
this
.
dispatchRequest
(
request
));
this
.
debugAdapter
.
onExit
(
code
=>
this
.
onDebugAdapterExit
(
code
));
this
.
debugAdapter
.
onError
(
err
=>
this
.
onDebugAdapterError
(
err
));
this
.
debugAdapter
.
onEvent
(
event
=>
this
.
onDapEvent
(
event
));
this
.
debugAdapter
.
onRequest
(
request
=>
this
.
dispatchRequest
(
request
));
this
.
debugAdapter
.
onExit
(
code
=>
this
.
onDebugAdapterExit
());
return
this
.
debugAdapter
.
startSession
();
});
return
this
.
debugAdapter
.
startSession
();
});
}
this
.
cachedInitDebugAdapterP
=
startSessionP
.
then
(()
=>
{
this
.
startTime
=
new
Date
().
getTime
();
},
err
=>
{
this
.
cachedInitDebugAdapterP
=
null
;
return
TPromise
.
wrapError
(
err
);
});
}
public
custom
(
request
:
string
,
args
:
any
):
TPromise
<
DebugProtocol
.
Response
>
{
return
this
.
send
(
request
,
args
);
return
this
.
cachedInitDebugAdapterP
;
}
private
send
<
R
extends
DebugProtocol
.
Response
>
(
command
:
string
,
args
:
any
,
cancelOnDisconnect
=
true
):
TPromise
<
R
>
{
return
this
.
initServer
().
then
(()
=>
{
return
this
.
startAdapter
().
then
(()
=>
{
const
cancellationSource
=
new
CancellationTokenSource
();
const
promise
=
this
.
internalSend
<
R
>
(
command
,
args
,
cancellationSource
.
token
).
then
(
response
=>
response
,
(
errorResponse
:
DebugProtocol
.
ErrorResponse
)
=>
{
const
error
=
errorResponse
&&
errorResponse
.
body
?
errorResponse
.
body
.
error
:
null
;
const
errorMessage
=
errorResponse
?
errorResponse
.
message
:
''
;
const
telemetryMessage
=
error
?
formatPII
(
error
.
format
,
true
,
error
.
variables
)
:
errorMessage
;
if
(
error
&&
error
.
sendTelemetry
)
{
/* __GDPR__
"debugProtocolErrorResponse" : {
"error" : { "classification": "CallstackOrException", "purpose": "FeatureInsight" }
}
*/
this
.
telemetryService
.
publicLog
(
'
debugProtocolErrorResponse
'
,
{
error
:
telemetryMessage
});
if
(
this
.
customTelemetryService
)
{
/* __GDPR__TODO__
The message is sent in the name of the adapter but the adapter doesn't know about it.
However, since adapters are an open-ended set, we can not declared the events statically either.
const
promise
=
this
.
internalSend
<
R
>
(
command
,
args
,
cancellationSource
.
token
).
then
(
response
=>
{
return
response
;
},
(
errorResponse
:
DebugProtocol
.
ErrorResponse
)
=>
{
const
error
=
errorResponse
&&
errorResponse
.
body
?
errorResponse
.
body
.
error
:
null
;
const
errorMessage
=
errorResponse
?
errorResponse
.
message
:
''
;
const
telemetryMessage
=
error
?
formatPII
(
error
.
format
,
true
,
error
.
variables
)
:
errorMessage
;
if
(
error
&&
error
.
sendTelemetry
)
{
/* __GDPR__
"debugProtocolErrorResponse" : {
"error" : { "classification": "CallstackOrException", "purpose": "FeatureInsight" }
}
*/
this
.
customTelemetryService
.
publicLog
(
'
debugProtocolErrorResponse
'
,
{
error
:
telemetryMessage
});
this
.
telemetryService
.
publicLog
(
'
debugProtocolErrorResponse
'
,
{
error
:
telemetryMessage
});
if
(
this
.
customTelemetryService
)
{
/* __GDPR__TODO__
The message is sent in the name of the adapter but the adapter doesn't know about it.
However, since adapters are an open-ended set, we can not declared the events statically either.
*/
this
.
customTelemetryService
.
publicLog
(
'
debugProtocolErrorResponse
'
,
{
error
:
telemetryMessage
});
}
}
}
const
userMessage
=
error
?
formatPII
(
error
.
format
,
false
,
error
.
variables
)
:
errorMessage
;
if
(
error
&&
error
.
url
)
{
const
label
=
error
.
urlLabel
?
error
.
urlLabel
:
nls
.
localize
(
'
moreInfo
'
,
"
More Info
"
);
return
TPromise
.
wrapError
<
R
>
(
errors
.
create
(
userMessage
,
{
actions
:
[
new
Action
(
'
debug.moreInfo
'
,
label
,
null
,
true
,
()
=>
{
window
.
open
(
error
.
url
);
return
TPromise
.
as
(
null
);
})]
}));
}
const
userMessage
=
error
?
formatPII
(
error
.
format
,
false
,
error
.
variables
)
:
errorMessage
;
if
(
error
&&
error
.
url
)
{
const
label
=
error
.
urlLabel
?
error
.
urlLabel
:
nls
.
localize
(
'
moreInfo
'
,
"
More Info
"
);
return
TPromise
.
wrapError
<
R
>
(
errors
.
create
(
userMessage
,
{
actions
:
[
new
Action
(
'
debug.moreInfo
'
,
label
,
null
,
true
,
()
=>
{
window
.
open
(
error
.
url
);
return
TPromise
.
as
(
null
);
})]
}));
}
return
errors
.
isPromiseCanceledError
(
errorResponse
)
?
undefined
:
TPromise
.
wrapError
<
R
>
(
new
Error
(
userMessage
));
});
if
(
errors
.
isPromiseCanceledError
(
errorResponse
))
{
return
TPromise
.
wrapError
<
R
>
(
<
any
>
errorResponse
);
}
return
TPromise
.
wrapError
<
R
>
(
new
Error
(
userMessage
));
});
if
(
cancelOnDisconnect
)
{
this
.
cancellationTokens
.
push
(
cancellationSource
);
...
...
@@ -397,7 +393,6 @@ export class RawDebugSession implements IRawSession {
return
this
.
send
<
DebugProtocol
.
LoadedSourcesResponse
>
(
'
loadedSources
'
,
args
);
}
public
threads
():
TPromise
<
DebugProtocol
.
ThreadsResponse
>
{
return
this
.
send
<
DebugProtocol
.
ThreadsResponse
>
(
'
threads
'
,
null
);
}
...
...
@@ -424,6 +419,10 @@ export class RawDebugSession implements IRawSession {
});
}
public
custom
(
request
:
string
,
args
:
any
):
TPromise
<
DebugProtocol
.
Response
>
{
return
this
.
send
(
request
,
args
);
}
public
getLengthInSeconds
():
number
{
return
(
new
Date
().
getTime
()
-
this
.
startTime
)
/
1000
;
}
...
...
@@ -503,14 +502,14 @@ export class RawDebugSession implements IRawSession {
return
TPromise
.
as
(
null
);
}
private
stopServer
():
TPromise
<
any
>
{
private
stopServer
(
error
?:
Error
):
TPromise
<
any
>
{
if
(
/* this.socket !== null */
this
.
debugAdapter
instanceof
SocketDebugAdapter
)
{
this
.
debugAdapter
.
stopSession
();
this
.
cachedInit
Serv
erP
=
null
;
this
.
cachedInit
DebugAdapt
erP
=
null
;
}
this
.
_onDidExitAdapter
.
fire
();
this
.
_onDidExitAdapter
.
fire
(
error
);
this
.
disconnected
=
true
;
if
(
!
this
.
debugAdapter
||
this
.
debugAdapter
instanceof
SocketDebugAdapter
)
{
return
TPromise
.
as
(
null
);
...
...
@@ -518,18 +517,18 @@ export class RawDebugSession implements IRawSession {
return
this
.
debugAdapter
.
stopSession
();
}
private
onDebugAdapterError
(
err
:
Error
):
void
{
this
.
notificationService
.
error
(
err
.
message
||
err
.
toString
());
this
.
stopServer
();
this
.
stopServer
(
err
);
}
private
onDebugAdapterExit
():
void
{
private
onDebugAdapterExit
(
code
:
number
):
void
{
this
.
debugAdapter
=
null
;
this
.
cachedInitServerP
=
null
;
if
(
!
this
.
disconnected
)
{
this
.
notificationService
.
error
(
nls
.
localize
(
'
debugAdapterCrash
'
,
"
Debug adapter process has terminated unexpectedly
"
));
this
.
cachedInitDebugAdapterP
=
null
;
if
(
!
this
.
disconnected
&&
code
!==
0
)
{
this
.
_onDidExitAdapter
.
fire
(
new
Error
(
`exit code:
${
code
}
`
));
}
else
{
// normal exit
this
.
_onDidExitAdapter
.
fire
();
}
this
.
_onDidExitAdapter
.
fire
();
}
}
src/vs/workbench/parts/debug/test/common/mockDebug.ts
浏览文件 @
73b7f479
...
...
@@ -157,7 +157,7 @@ export class MockSession implements ISession {
return
null
;
}
get
onDidExitAdapter
():
Event
<
void
>
{
get
onDidExitAdapter
():
Event
<
Error
>
{
return
null
;
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录