{"id":102389,"date":"2019-04-05T07:00:00","date_gmt":"2019-04-05T14:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=102389"},"modified":"2019-06-06T17:41:28","modified_gmt":"2019-06-07T00:41:28","slug":"20190405-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20190405-00\/?p=102389","title":{"rendered":"What does it mean when my attempt to stop a Windows NT service fails with ERROR_BROKEN_PIPE?"},"content":{"rendered":"<p>A customer reported that they had a sporadic problem: Their product includes a Windows NT service, and when their client program tries to stop the service, it sometimes fails with <code>ERROR_<\/code><code>BROKEN_<\/code><code>PIPE<\/code>. Their client program is written in C#, so it uses the <code>Service&shy;Controller.<\/code><code>Stop<\/code> method to stop the service, and the failure is reported in the form of an exception. In Win32, this turns into a call to the <code>Control&shy;Service<\/code> function with the <code>SERVICE_<\/code><code>CONTROL_<\/code><code>STOP<\/code> code. <\/p>\n<p>Under what conditions would an attempt to stop a service result in the error <code>ERROR_<\/code><code>BROKEN_<\/code><code>PIPE<\/code>? <\/p>\n<p>One of the developer support escalation engineers used psychic powers: <\/p>\n<blockquote CLASS=\"q\">\n<p>Does your service terminate itself before the call to its <code>Handler&shy;Ex<\/code> routine returns from the <code>SERVICE_<\/code><code>CONTROL_<\/code><code>STOP<\/code> request, or before the call to <code>Start&shy;Service&shy;Ctrl&shy;Dispatcher<\/code> returns? <\/p>\n<p>I&#8217;m guessing that the <code>ERROR_<\/code><code>BROKEN_<\/code><code>PIPE<\/code> arises because the service process terminated itself while the Service Control Manager was still talking to it, waiting for the service to report that it finished processing the <code>SERVICE_<\/code><code>CONTROL_<\/code><code>STOP<\/code> request. The error is <code>ERROR_<\/code><code>BROKEN_<\/code><code>PIPE<\/code> because the process on the other end of the pipe (the service) died. <\/p>\n<\/blockquote>\n<p>The customer agreed that this was a possibility: When the service receives the <code>SERVICE_<\/code><code>CONTROL_<\/code><code>STOP<\/code> request, it signals a helper thread to clean up, and that helper thread may finish its cleanup and terminate the service process before the main thread can report a successful stop to the Service Control Manager. <\/p>\n<p>A short time later, the customer reported back and confirmed that when they forced the race condition to occur, they indeed got the <code>ERROR_<\/code><code>BROKEN_<\/code><code>PIPE<\/code> error code. <\/p>\n<p>I like this example of psychic debugging because it demonstrates how you can take something you know (<code>ERROR_<\/code><code>BROKEN_<\/code><code>PIPE<\/code> means that two processes were talking to each other over a pipe, and one side suddenly terminated), and think about how it could apply to something you don&#8217;t know (surmising that the Service Control Manager uses a pipe to talk to the service). <\/p>\n","protected":false},"excerpt":{"rendered":"<p>The Service Control Manager lost contact with the service, but why?<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-102389","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>The Service Control Manager lost contact with the service, but why?<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/102389","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=102389"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/102389\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=102389"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=102389"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=102389"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}