@@ -156,31 +156,56 @@ var serveCommand = cli.Command{
156156 },
157157}
158158
159- func setupDumpStacks () error {
160- // Windows does not support signals like *nix systems. So instead of
161- // trapping on SIGUSR1 to dump stacks, we wait on a Win32 event to be
162- // signaled. ACL'd to builtin administrators and local system
163- event := "Global\\ containerd-shim-runhcs-v1-" + fmt .Sprint (os .Getpid ())
159+ // createEvent creates a Windows event ACL'd to builtin administrator
160+ // and local system. Can use docker-signal to signal the event.
161+ func createEvent (event string ) (windows.Handle , error ) {
164162 ev , _ := windows .UTF16PtrFromString (event )
165163 sd , err := winio .SddlToSecurityDescriptor ("D:P(A;;GA;;;BA)(A;;GA;;;SY)" )
166164 if err != nil {
167- return errors .Wrapf (err , "failed to get security descriptor for debug stackdump event '%s'" , event )
165+ return 0 , errors .Wrapf (err , "failed to get security descriptor for event '%s'" , event )
168166 }
169167 var sa windows.SecurityAttributes
170168 sa .Length = uint32 (unsafe .Sizeof (sa ))
171169 sa .InheritHandle = 1
172170 sa .SecurityDescriptor = uintptr (unsafe .Pointer (& sd [0 ]))
173171 h , err := windows .CreateEvent (& sa , 0 , 0 , ev )
174172 if h == 0 || err != nil {
175- return errors .Wrapf (err , "failed to create debug dump stack event '%s'" , event )
173+ return 0 , errors .Wrapf (err , "failed to create event '%s'" , event )
174+ }
175+ return h , nil
176+ }
177+
178+ // setupDebuggerEvent listens for an event to allow a debugger such as delve
179+ // to attach for advanced debugging. It's called when handling a ContainerCreate
180+ func setupDebuggerEvent () {
181+ if os .Getenv ("CONTAINERD_SHIM_RUNHCS_V1_WAIT_DEBUGGER" ) == "" {
182+ return
183+ }
184+ event := "Global\\ debugger-" + fmt .Sprint (os .Getpid ())
185+ handle , err := createEvent (event )
186+ if err != nil {
187+ return
188+ }
189+ logrus .Infof ("Halting until %s is signalled" , event )
190+ windows .WaitForSingleObject (handle , windows .INFINITE )
191+ return
192+ }
193+
194+ // setupDumpStacks listens for an event which when signalled dumps the
195+ // stacks from this process to the log output.
196+ func setupDumpStacks () {
197+ event := "Global\\ stackdump-" + fmt .Sprint (os .Getpid ())
198+ handle , err := createEvent (event )
199+ if err != nil {
200+ return
176201 }
177202 go func () {
178203 for {
179- windows .WaitForSingleObject (h , windows .INFINITE )
204+ windows .WaitForSingleObject (handle , windows .INFINITE )
180205 dumpStacks ()
181206 }
182207 }()
183- return nil
208+ return
184209}
185210
186211func dumpStacks () {
0 commit comments