@@ -36,52 +36,78 @@ defmodule ElixirLS.DebugAdapter.Stacktrace do
36
36
def get ( pid ) do
37
37
case :dbg_iserver . safe_call ( { :get_meta , pid } ) do
38
38
{ :ok , meta_pid } ->
39
- [ { level , { module , function , args } } | backtrace_rest ] =
40
- :int . meta ( meta_pid , :backtrace , :all )
41
-
42
- messages = :int . meta ( meta_pid , :messages )
43
-
44
- first_frame = % Frame {
45
- level: level ,
46
- module: module ,
47
- function: { function , get_arity ( args ) } ,
48
- args: args ,
49
- file: get_file ( module ) ,
50
- # vscode raises invalid request when line is nil
51
- line: break_line ( pid ) || 1 ,
52
- bindings: get_bindings ( meta_pid , level ) ,
53
- messages: messages
54
- }
55
-
56
- # If backtrace_rest is empty, calling stack_frames causes an exception
57
- other_frames =
58
- case backtrace_rest do
59
- [ ] ->
60
- [ ]
61
-
62
- _ ->
63
- frames = List . zip ( [ backtrace_rest , stack_frames ( meta_pid , level ) ] )
64
-
65
- for { { level , { mod , function , args } } , { level , { mod , line } , bindings } } <- frames do
66
- % Frame {
67
- level: level ,
68
- module: mod ,
69
- function: { function , get_arity ( args ) } ,
70
- args: args ,
71
- file: get_file ( mod ) ,
72
- # vscode raises invalid request when line is nil
73
- line: line || 1 ,
74
- bindings: Enum . into ( bindings , % { } ) ,
75
- messages: messages
76
- }
39
+ parent = self ( )
40
+ ref = Process . monitor ( meta_pid )
41
+
42
+ meta_query_pid =
43
+ spawn ( fn ->
44
+ [ { level , { module , function , args } } | backtrace_rest ] =
45
+ :int . meta ( meta_pid , :backtrace , :all )
46
+
47
+ messages = :int . meta ( meta_pid , :messages )
48
+
49
+ first_frame = % Frame {
50
+ level: level ,
51
+ module: module ,
52
+ function: { function , get_arity ( args ) } ,
53
+ args: args ,
54
+ file: get_file ( module ) ,
55
+ # vscode raises invalid request when line is nil
56
+ line: break_line ( pid ) || 1 ,
57
+ bindings: get_bindings ( meta_pid , level ) ,
58
+ messages: messages
59
+ }
60
+
61
+ # If backtrace_rest is empty, calling stack_frames causes an exception
62
+ other_frames =
63
+ case backtrace_rest do
64
+ [ ] ->
65
+ [ ]
66
+
67
+ _ ->
68
+ frames = List . zip ( [ backtrace_rest , stack_frames ( meta_pid , level ) ] )
69
+
70
+ for { { level , { mod , function , args } } , { level , { mod , line } , bindings } } <- frames do
71
+ % Frame {
72
+ level: level ,
73
+ module: mod ,
74
+ function: { function , get_arity ( args ) } ,
75
+ args: args ,
76
+ file: get_file ( mod ) ,
77
+ # vscode raises invalid request when line is nil
78
+ line: line || 1 ,
79
+ bindings: Enum . into ( bindings , % { } ) ,
80
+ messages: messages
81
+ }
82
+ end
77
83
end
78
- end
79
84
80
- [ first_frame | other_frames ]
85
+ send ( parent , { :ok , [ first_frame | other_frames ] } )
86
+ end )
87
+
88
+ receive do
89
+ { :ok , trace } ->
90
+ trace
91
+
92
+ { :DOWN , _ , :process , ^ meta_pid , reason } ->
93
+ Process . exit ( meta_query_pid , :kill )
94
+
95
+ Output . debugger_console (
96
+ "Meta process down fo pid #{ inspect ( pid ) } : #{ inspect ( reason ) } \n "
97
+ )
98
+
99
+ [ ]
100
+ after
101
+ 5000 ->
102
+ Process . exit ( meta_query_pid , :kill )
103
+ Process . demonitor ( ref , false )
104
+ Output . debugger_console ( "Timed out while obtaining meta for pid #{ inspect ( pid ) } \n " )
105
+ [ ]
106
+ end
81
107
82
108
error ->
83
- Output . debugger_important (
84
- "Failed to obtain meta for pid #{ inspect ( pid ) } : #{ inspect ( error ) } "
109
+ Output . debugger_console (
110
+ "Failed to obtain meta for pid #{ inspect ( pid ) } : #{ inspect ( error ) } \n "
85
111
)
86
112
87
113
[ ]
0 commit comments