attachListener_windows.cpp revision 1879:f95d63e2154a
192108Sphk/*
292108Sphk * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
392108Sphk * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
492108Sphk *
592108Sphk * This code is free software; you can redistribute it and/or modify it
692108Sphk * under the terms of the GNU General Public License version 2 only, as
792108Sphk * published by the Free Software Foundation.
892108Sphk *
992108Sphk * This code is distributed in the hope that it will be useful, but WITHOUT
1092108Sphk * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1192108Sphk * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1292108Sphk * version 2 for more details (a copy is included in the LICENSE file that
1392108Sphk * accompanied this code).
1492108Sphk *
1592108Sphk * You should have received a copy of the GNU General Public License version
1692108Sphk * 2 along with this work; if not, write to the Free Software Foundation,
1792108Sphk * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1892108Sphk *
1992108Sphk * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2092108Sphk * or visit www.oracle.com if you need additional information or have any
2192108Sphk * questions.
2292108Sphk *
2392108Sphk */
2492108Sphk
2592108Sphk#include "precompiled.hpp"
2692108Sphk#include "runtime/interfaceSupport.hpp"
2792108Sphk#include "runtime/os.hpp"
2892108Sphk#include "services/attachListener.hpp"
2992108Sphk#include "services/dtraceAttacher.hpp"
3092108Sphk
3192108Sphk#include <windows.h>
3292108Sphk#include <signal.h>             // SIGBREAK
3392108Sphk
3492108Sphk// The AttachListener thread services a queue of operations. It blocks in the dequeue
3592108Sphk// function until an operation is enqueued. A client enqueues an operation by creating
3692108Sphk// a thread in this process using the Win32 CreateRemoteThread function. That thread
3792108Sphk// executes a small stub generated by the client. The stub invokes the
3892108Sphk// JVM_EnqueueOperation function which checks the operation parameters and enqueues
3992108Sphk// the operation to the queue serviced by the attach listener. The thread created by
40105540Sphk// the client is a native thread and is restricted to a single page of stack. To keep
4192108Sphk// it simple operations are pre-allocated at initialization time. An enqueue thus
4292108Sphk// takes a preallocated operation, populates the operation parameters, adds it to
4392108Sphk// queue and wakes up the attach listener.
4492108Sphk//
4592108Sphk// When an operation has completed the attach listener is required to send the
4696952Sphk// operation result and any result data to the client. In this implementation the
4792108Sphk// client is a pipe server. In the enqueue operation it provides the name of pipe
4892108Sphk// to this process. When the operation is completed this process opens the pipe and
4992108Sphk// sends the result and output back to the client. Note that writing to the pipe
5092108Sphk// (and flushing the output) is a blocking operation. This means that a non-responsive
5192108Sphk// client could potentially hang the attach listener thread indefinitely. In that
5292108Sphk// case no new operations would be executed but the VM would continue as normal.
5392108Sphk// As only suitably privileged processes can open this process we concluded that
5492108Sphk// this wasn't worth worrying about.
5592108Sphk
5692108Sphk
5792108Sphk// forward reference
5892108Sphkclass Win32AttachOperation;
5992108Sphk
6092108Sphk
6192108Sphkclass Win32AttachListener: AllStatic {
6292108Sphk private:
6392108Sphk  enum {
6492108Sphk    preallocate_count = 4                   // number of preallocated operations
6593776Sphk  };
6693776Sphk
6793776Sphk  // protects the preallocated list and the operation list
6893776Sphk  static HANDLE _mutex;
6995321Sphk
7092108Sphk  // head of preallocated operations list
7192108Sphk  static Win32AttachOperation* _avail;
7292108Sphk
7392108Sphk  // head and tail of enqueue operations list
7492371Sphk  static Win32AttachOperation* _head;
7592371Sphk  static Win32AttachOperation* _tail;
76104057Sphk
77104057Sphk
7892108Sphk  static Win32AttachOperation* head()                       { return _head; }
7992108Sphk  static void set_head(Win32AttachOperation* head)          { _head = head; }
8092108Sphk
8192108Sphk  static Win32AttachOperation* tail()                       { return _tail; }
8293776Sphk  static void set_tail(Win32AttachOperation* tail)          { _tail = tail; }
8392108Sphk
8492108Sphk
8592108Sphk  // used to wakeup the listener
8692108Sphk  static HANDLE _wakeup;
8792108Sphk  static HANDLE wakeup()                                    { return _wakeup; }
8892108Sphk
8992108Sphk public:
9092108Sphk  enum {
9192108Sphk    ATTACH_ERROR_DISABLED               = 100,              // error codes
9292108Sphk    ATTACH_ERROR_RESOURCE               = 101,
9392108Sphk    ATTACH_ERROR_ILLEGALARG             = 102,
9492108Sphk    ATTACH_ERROR_INTERNAL               = 103
9592108Sphk  };
9692108Sphk
9792108Sphk  static int init();
9892108Sphk  static HANDLE mutex()                                     { return _mutex; }
9992108Sphk
10092108Sphk  static Win32AttachOperation* available()                  { return _avail; }
10192108Sphk  static void set_available(Win32AttachOperation* avail)    { _avail = avail; }
10292108Sphk
10392108Sphk  // enqueue an operation to the end of the list
10492108Sphk  static int enqueue(char* cmd, char* arg1, char* arg2, char* arg3, char* pipename);
10592108Sphk
10692108Sphk  // dequeue an operation from from head of the list
10792108Sphk  static Win32AttachOperation* dequeue();
10892108Sphk};
10992108Sphk
11092108Sphk// statics
11192108SphkHANDLE Win32AttachListener::_mutex;
11292108SphkHANDLE Win32AttachListener::_wakeup;
11392108SphkWin32AttachOperation* Win32AttachListener::_avail;
11492108SphkWin32AttachOperation* Win32AttachListener::_head;
11592108SphkWin32AttachOperation* Win32AttachListener::_tail;
11692108Sphk
11792108Sphk
11892108Sphk// Win32AttachOperation is an AttachOperation that additionally encapsulates the name
11992108Sphk// of a pipe which is used to send the operation reply/output to the client.
12092108Sphk// Win32AttachOperation can also be linked in a list.
12192108Sphk
12292108Sphkclass Win32AttachOperation: public AttachOperation {
12392108Sphk private:
124107522Sphk  friend class Win32AttachListener;
125107522Sphk
126107522Sphk  enum {
127107522Sphk    pipe_name_max = 256             // maximum pipe name
128107522Sphk  };
129107522Sphk
130107522Sphk  char _pipe[pipe_name_max+1];
131107522Sphk
132107522Sphk  const char* pipe() const                              { return _pipe; }
133107522Sphk  void set_pipe(const char* pipe) {
134107522Sphk    assert(strlen(pipe) <= pipe_name_max, "execeds maximum length of pipe name");
135107522Sphk    strcpy(_pipe, pipe);
136107522Sphk  }
137107522Sphk
138107522Sphk  HANDLE open_pipe();
139107522Sphk  static BOOL write_pipe(HANDLE hPipe, char* buf, int len);
140107522Sphk
141107522Sphk  Win32AttachOperation* _next;
142107522Sphk
143107522Sphk  Win32AttachOperation* next() const                    { return _next; }
144107522Sphk  void set_next(Win32AttachOperation* next)             { _next = next; }
145107522Sphk
146107522Sphk  // noarg constructor as operation is preallocated
147107522Sphk  Win32AttachOperation() : AttachOperation("<noname>") {
148107522Sphk    set_pipe("<nopipe>");
149107522Sphk    set_next(NULL);
150107522Sphk  }
151107522Sphk
152107522Sphk public:
153107522Sphk  void Win32AttachOperation::complete(jint result, bufferedStream* result_stream);
154107522Sphk};
155107522Sphk
15693776Sphk
15792108Sphk// preallocate the required number of operations
15892108Sphkint Win32AttachListener::init() {
15992108Sphk  _mutex = (void*)::CreateMutex(NULL, FALSE, NULL);
16092108Sphk  guarantee(_mutex != (HANDLE)NULL, "mutex creation failed");
16192108Sphk
16292108Sphk  _wakeup = ::CreateSemaphore(NULL, 0, 1, NULL);
16392108Sphk  guarantee(_wakeup != (HANDLE)NULL, "semaphore creation failed");
164107522Sphk
165107522Sphk  set_head(NULL);
166107522Sphk  set_tail(NULL);
16794287Sphk
16892108Sphk  // preallocate a few operations
16992108Sphk  set_available(NULL);
17092108Sphk  for (int i=0; i<preallocate_count; i++) {
17192108Sphk    Win32AttachOperation* op = new Win32AttachOperation();
17292108Sphk    op->set_next(available());
17392108Sphk    set_available(op);
17494287Sphk  }
17592108Sphk
17692108Sphk  return 0;
17792108Sphk}
17892108Sphk
17992108Sphk// Enqueue an operation. This is called from a native thread that is not attached to VM.
180104195Sphk// Also we need to be careful not to execute anything that results in more than a 4k stack.
18192108Sphk//
18292108Sphkint Win32AttachListener::enqueue(char* cmd, char* arg0, char* arg1, char* arg2, char* pipename) {
183107522Sphk  // listener not running
184107522Sphk  if (!AttachListener::is_initialized()) {
185107522Sphk    return ATTACH_ERROR_DISABLED;
186107522Sphk  }
187107832Sphk
188107522Sphk  // check that all paramteres to the operation
189107522Sphk  if (strlen(cmd) > AttachOperation::name_length_max) return ATTACH_ERROR_ILLEGALARG;
190107832Sphk  if (strlen(arg0) > AttachOperation::arg_length_max) return ATTACH_ERROR_ILLEGALARG;
191107522Sphk  if (strlen(arg0) > AttachOperation::arg_length_max) return ATTACH_ERROR_ILLEGALARG;
192107832Sphk  if (strlen(pipename) > Win32AttachOperation::pipe_name_max) return ATTACH_ERROR_ILLEGALARG;
193107522Sphk
194107522Sphk  // check for a well-formed pipename
195107522Sphk  if (strstr(pipename, "\\\\.\\pipe\\") != pipename) return ATTACH_ERROR_ILLEGALARG;
196107522Sphk
197107522Sphk  // grab the lock for the list
198107522Sphk  DWORD res = ::WaitForSingleObject(mutex(), INFINITE);
199107522Sphk  if (res != WAIT_OBJECT_0) {
200107522Sphk    return ATTACH_ERROR_INTERNAL;
201107522Sphk  }
202107522Sphk
20392108Sphk  // try to get an operation from the available list
204104057Sphk  Win32AttachOperation* op = available();
205104195Sphk  if (op != NULL) {
206104057Sphk    set_available(op->next());
207104057Sphk
20892108Sphk    // add to end (tail) of list
20992108Sphk    op->set_next(NULL);
21092108Sphk    if (tail() == NULL) {
21192108Sphk      set_head(op);
21292108Sphk    } else {
21392108Sphk      tail()->set_next(op);
21492108Sphk    }
21592108Sphk    set_tail(op);
21694287Sphk
21794287Sphk    op->set_name(cmd);
21894287Sphk    op->set_arg(0, arg0);
21994287Sphk    op->set_arg(1, arg1);
22094287Sphk    op->set_arg(2, arg2);
22194287Sphk    op->set_pipe(pipename);
22294287Sphk
22394287Sphk    // wakeup the thread waiting for operations
22494287Sphk    ::ReleaseSemaphore(wakeup(), 1, NULL);
22594287Sphk  }
22694287Sphk  ::ReleaseMutex(mutex());
22794287Sphk
22898066Sphk  return (op != NULL) ? 0 : ATTACH_ERROR_RESOURCE;
22992108Sphk}
23094287Sphk
23195310Sphk
23295038Sphk// dequeue the operation from the head of the operation list. If
23395038SphkWin32AttachOperation* Win32AttachListener::dequeue() {
23495038Sphk  for (;;) {
23595038Sphk    DWORD res = ::WaitForSingleObject(wakeup(), INFINITE);
23695038Sphk    guarantee(res == WAIT_OBJECT_0, "wait failed");
23795038Sphk
23895038Sphk    res = ::WaitForSingleObject(mutex(), INFINITE);
23995038Sphk    guarantee(res == WAIT_OBJECT_0, "wait failed");
24095038Sphk
24195310Sphk    Win32AttachOperation* op = head();
24292108Sphk    if (op != NULL) {
243104081Sphk      set_head(op->next());
244104195Sphk      if (head() == NULL) {     // list is empty
245104081Sphk        set_tail(NULL);
246104081Sphk      }
24792108Sphk    }
24892108Sphk    ::ReleaseMutex(mutex());
24992108Sphk
25092108Sphk    if (op != NULL) {
251104195Sphk      return op;
25292108Sphk    }
25392108Sphk  }
25492108Sphk}
25592108Sphk
25692108Sphk
257104087Sphk// open the pipe to the client
25892108SphkHANDLE Win32AttachOperation::open_pipe() {
25992108Sphk  HANDLE hPipe;
26092108Sphk
26192108Sphk  hPipe = ::CreateFile( pipe(),  // pipe name
262106101Sphk                        GENERIC_WRITE,   // write only
263106101Sphk                        0,              // no sharing
264106101Sphk                        NULL,           // default security attributes
265106101Sphk                        OPEN_EXISTING,  // opens existing pipe
266106101Sphk                        0,              // default attributes
267106101Sphk                        NULL);          // no template file
26895323Sphk
269105540Sphk  if (hPipe != INVALID_HANDLE_VALUE) {
270105540Sphk    // shouldn't happen as there is a pipe created per operation
27194287Sphk    if (::GetLastError() == ERROR_PIPE_BUSY) {
27292108Sphk      return INVALID_HANDLE_VALUE;
27392108Sphk    }
274105540Sphk  }
275105540Sphk  return hPipe;
276105540Sphk}
277105540Sphk
278105540Sphk// write to the pipe
279105540SphkBOOL Win32AttachOperation::write_pipe(HANDLE hPipe, char* buf, int len) {
280105540Sphk  do {
281105540Sphk    DWORD nwrote;
28292108Sphk
28392108Sphk    BOOL fSuccess = WriteFile(  hPipe,                  // pipe handle
28492108Sphk                                (LPCVOID)buf,           // message
285104064Sphk                                (DWORD)len,             // message length
286107522Sphk                                &nwrote,                // bytes written
287104064Sphk                                NULL);                  // not overlapped
288104064Sphk    if (!fSuccess) {
289104064Sphk      return fSuccess;
290104064Sphk    }
291104064Sphk    buf += nwrote;
292104064Sphk    len -= nwrote;
293104064Sphk  }
294104064Sphk  while (len > 0);
295104195Sphk  return TRUE;
296104195Sphk}
297104064Sphk
298104064Sphk// Complete the operation:
299104064Sphk//   - open the pipe to the client
300104064Sphk//   - write the operation result (a jint)
301104064Sphk//   - write the operation output (the result stream)
302104064Sphk//
303104064Sphkvoid Win32AttachOperation::complete(jint result, bufferedStream* result_stream) {
304104064Sphk  JavaThread* thread = JavaThread::current();
305104064Sphk  ThreadBlockInVM tbivm(thread);
306104064Sphk
307104064Sphk  thread->set_suspend_equivalent();
308104064Sphk  // cleared by handle_special_suspend_equivalent_condition() or
309104064Sphk  // java_suspend_self() via check_and_wait_while_suspended()
310104064Sphk
311104064Sphk  HANDLE hPipe = open_pipe();
312104064Sphk  if (hPipe != INVALID_HANDLE_VALUE) {
313104064Sphk    BOOL fSuccess;
314104064Sphk
315104064Sphk    char msg[32];
316104064Sphk    sprintf(msg, "%d\n", result);
317104064Sphk
318104064Sphk    fSuccess = write_pipe(hPipe, msg, (int)strlen(msg));
319105542Sphk    if (fSuccess) {
320105957Sphk      write_pipe(hPipe, (char*) result_stream->base(), (int)(result_stream->size()));
321105957Sphk    }
322105957Sphk
323105957Sphk    // Need to flush buffers
324105957Sphk    FlushFileBuffers(hPipe);
325104064Sphk    CloseHandle(hPipe);
326104064Sphk  }
327104064Sphk
328104064Sphk  DWORD res = ::WaitForSingleObject(Win32AttachListener::mutex(), INFINITE);
329104064Sphk  if (res == WAIT_OBJECT_0) {
330105957Sphk
331105957Sphk    // put the operation back on the available list
332105957Sphk    set_next(Win32AttachListener::available());
333105957Sphk    Win32AttachListener::set_available(this);
334105957Sphk
335107116Sphk    ::ReleaseMutex(Win32AttachListener::mutex());
336105957Sphk  }
337105957Sphk
338104064Sphk  // were we externally suspended while we were waiting?
339104064Sphk  thread->check_and_wait_while_suspended();
340104064Sphk}
341104064Sphk
342104064Sphk
343105957Sphk// AttachOperation functions
344105957Sphk
345105957SphkAttachOperation* AttachListener::dequeue() {
346105957Sphk  JavaThread* thread = JavaThread::current();
347104064Sphk  ThreadBlockInVM tbivm(thread);
348105542Sphk
349105542Sphk  thread->set_suspend_equivalent();
350104064Sphk  // cleared by handle_special_suspend_equivalent_condition() or
351104064Sphk  // java_suspend_self() via check_and_wait_while_suspended()
352104064Sphk
353104064Sphk  AttachOperation* op = Win32AttachListener::dequeue();
354104064Sphk
355104064Sphk  // were we externally suspended while we were waiting?
356104064Sphk  thread->check_and_wait_while_suspended();
357107522Sphk
358107522Sphk  return op;
359107522Sphk}
360107522Sphk
361107522Sphkint AttachListener::pd_init() {
362107522Sphk  return Win32AttachListener::init();
363107522Sphk}
364107522Sphk
365107522Sphk// always startup on Windows NT/2000/XP
366107522Sphkbool AttachListener::init_at_startup() {
367107522Sphk  return os::win32::is_nt();
368107522Sphk}
369107522Sphk
370107522Sphk// no trigger mechanism on Windows to start Attach Listener lazily
371107522Sphkbool AttachListener::is_init_trigger() {
372107522Sphk  return false;
373107522Sphk}
374107522Sphk
375107522Sphkvoid AttachListener::abort() {
376107522Sphk  // nothing to do
377107522Sphk}
378107522Sphk
379107522Sphkvoid AttachListener::pd_data_dump() {
380107522Sphk  os::signal_notify(SIGBREAK);
381107522Sphk}
382107522Sphk
383107522SphkAttachOperationFunctionInfo* AttachListener::pd_find_operation(const char* n) {
384107522Sphk  return NULL;
385107522Sphk}
38692108Sphk
387105542Sphkjint AttachListener::pd_set_flag(AttachOperation* op, outputStream* out) {
38892108Sphk  out->print_cr("flag '%s' cannot be changed", op->arg(0));
38992108Sphk  return JNI_ERR;
39092108Sphk}
39192108Sphk
39292108Sphkvoid AttachListener::pd_detachall() {
39392108Sphk  // do nothing for now
39492108Sphk}
395104064Sphk
39692108Sphk// Native thread started by remote client executes this.
39792108Sphkextern "C" {
39892108Sphk  JNIEXPORT jint JNICALL
39992108Sphk    JVM_EnqueueOperation(char* cmd, char* arg0, char* arg1, char* arg2, char* pipename) {
40092108Sphk      return (jint)Win32AttachListener::enqueue(cmd, arg0, arg1, arg2, pipename);
40192108Sphk    }
40292108Sphk
40392108Sphk} // extern
40492108Sphk