4552N/A * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. 0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 0N/A * This code is free software; you can redistribute it and/or modify it 0N/A * under the terms of the GNU General Public License version 2 only, as 0N/A * published by the Free Software Foundation. 0N/A * This code is distributed in the hope that it will be useful, but WITHOUT 0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 0N/A * version 2 for more details (a copy is included in the LICENSE file that 0N/A * accompanied this code). 0N/A * You should have received a copy of the GNU General Public License version 0N/A * 2 along with this work; if not, write to the Free Software Foundation, 0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1472N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 0N/A// Standard Memory Implementation Details 0N/A// create the PerfData memory region in standard memory. 0N/A // allocate an aligned chuck of memory 0N/A// delete the PerfData memory region 0N/A // there are no persistent external resources to cleanup for standard 0N/A // memory. since DestroyJavaVM does not support unloading of the JVM, 0N/A // cleanup of the memory resource is not performed. The memory will be 0N/A // reclaimed by the OS upon termination of the process. 0N/A// save the specified memory region to the given file 0N/A warning(
"Could not create Perfdata save file: %s: %s\n",
0N/A warning(
"Could not write Perfdata save file: %s: %s\n",
0N/A// Shared Memory Implementation Details 0N/A// Note: the win32 shared memory implementation uses two objects to represent 0N/A// the shared memory: a windows kernel based file mapping object and a backing 0N/A// store file. On windows, the name space for shared memory is a kernel 0N/A// based name space that is disjoint from other win32 name spaces. Since Java 0N/A// is unaware of this name space, a parallel file system based name space is 0N/A// maintained, which provides a common file system based shared memory name 0N/A// space across the supported platforms and one that Java apps can deal with 0N/A// through simple file apis. 0N/A// For performance and resource cleanup reasons, it is recommended that the 0N/A// user specific directory and the backing store file be stored in either a 0N/A// RAM based file system or a local disk based file system. Network based 0N/A// file systems are not recommended for performance reasons. In addition, 0N/A// use of SMB network based file systems may result in unsuccesful cleanup 0N/A// of the disk based resource on exit of the VM. The Windows TMP and TEMP 0N/A// environement variables, as used by the GetTempPath() Win32 API (see 0N/A// user specific directory and the shared memory backing store file. 0N/A// return the user specific temporary directory name. 0N/A// the caller is expected to free the allocated memory. 0N/A // construct the path name to user specific tmp directory 0N/A// convert the given file name into a process id. if the file 0N/A// does not meet the file naming constraints, return 0. 0N/A // a filename that doesn't begin with a digit is not a 0N/A // candidate for conversion. 0N/A // check if file name can be converted to an integer without 0N/A // any leftover characters. 0N/A // check for left over characters. If any, then the filename is 0N/A // not a candidate for conversion. 0N/A // successful conversion, return the pid 0N/A// check if the given path is considered a secure directory for 0N/A// the backing store files. Returns true if the directory exists 0N/A// and is considered a secure location. Returns false if the path 605N/A// is a symbolic link or if an error occurred. 0N/A // unexpected error, declare the path insecure 0N/A // we don't accept any redirection for the user specific directory 0N/A // so declare the path insecure. This may be too conservative, 0N/A // as some types of reparse points might be acceptable, but it 0N/A // is probably more secure to avoid these conditions. 0N/A // this is the expected case. Since windows supports symbolic 0N/A // links to directories only, not to files, there is no need 0N/A // to check for open write permissions on the directory. If the 0N/A // directory has open write permissions, any files deposited that 0N/A // are not expected will be removed by the cleanup code. 0N/A // this is either a regular file or some other type of file, 0N/A // any of which are unexpected and therefore insecure. 0N/A warning(
"%s is not a directory, file attributes = " 0N/A// return the user name for the owner of this process 0N/A// the caller is expected to free the allocated memory. 0N/A /* get the user name. This code is adapted from code found in 0N/A * source, the call to GetUserName is avoided because of a resulting 0N/A * increase in footprint of 100K. 0N/A// return the name of the user that owns the process identified by vmid. 0N/A// This method uses a slow directory search algorithm to find the backing 0N/A// store file for the specified vmid and returns the user name, as determined 0N/A// by the user name suffix of the hsperfdata_<username> directory name. 0N/A// the caller is expected to free the allocated memory. 0N/A // for each entry in the directory that matches the pattern hsperfdata_*, 0N/A // open the directory and check if the file for the given vmid exists. 0N/A // The file with the expected name and the latest creation date is used 0N/A // to determine the user name for the process id. 0N/A // check if the directory entry is a hsperfdata file 0N/A // Since we don't create the backing store files in directories 0N/A // pointed to by symbolic links, we also don't follow them when 0N/A // looking for the files. We check for a symbolic link after the 0N/A // call to opendir in order to eliminate a small window where the 0N/A // symlink can be exploited. 0N/A // skip over files that are not regular files. 2108N/A // If we found a matching file with a newer creation time, then 2108N/A // save the user name. The newer creation time indicates that 2108N/A // we found a newer incarnation of the process associated with 2108N/A // vmid. Due to the way that Windows recycles pids and the fact 2108N/A // that we can't delete the file from the file system namespace 2108N/A // until last close, it is possible for there to be more than 2108N/A // one hsperfdata file with a name matching vmid (diff users). 2108N/A // We no longer ignore hsperfdata files where (st_size == 0). 2108N/A // In this function, all we're trying to do is determine the 2108N/A // name of the user that owns the process associated with vmid 2108N/A // so the size doesn't matter. Very rarely, we have observed 2108N/A // hsperfdata files where (st_size == 0) and the st_size field 2108N/A // later becomes the expected value. 0N/A// return the name of the user that owns the process identified by vmid. 0N/A// note: this method should only be used via the Perf native methods. 0N/A// There are various costs to this method and limiting its use to the 0N/A// Perf native methods limits the impact to monitoring applications only. 0N/A // A fast implementation is not provided at this time. It's possible 0N/A // to provide a fast process id to user name mapping function using 0N/A // the win32 apis, but the default ACL for the process object only 0N/A // allows processes with the same owner SID to acquire the process 0N/A // handle (via OpenProcess(PROCESS_QUERY_INFORMATION)). It's possible 0N/A // to have the JVM change the ACL for the process object to allow arbitrary 0N/A // users to access the process handle and the process security token. 0N/A // The security ramifications need to be studied before providing this 0N/A// return the name of the shared memory file mapping object for the 0N/A// named shared memory region for the given user name and vmid. 0N/A// The file mapping object's name is not the file name. It is a name 0N/A// in a separate name space. 0N/A// the caller is expected to free the allocated memory. 0N/A // construct file mapping object's name, add 3 for two '_' and a 0N/A // the id is converted to an unsigned value here because win32 allows 0N/A // negative process ids. However, OpenFileMapping API complains 0N/A // about a name containing a '-' characters. 0N/A// return the file name of the backing store file for the named 0N/A// shared memory region for the given user name and vmid. 0N/A// the caller is expected to free the allocated memory. 0N/A // add 2 for the file separator and a null terminator. 0N/A// this method removes the file with the given file name. 0N/A// Note: if the indicated file is on an SMB network file system, this 0N/A// method may be unsuccessful in removing the file. 0N/A// returns true if the process represented by pid is alive, otherwise 0N/A// returns false. the validity of the result is only accurate if the 0N/A// target process is owned by the same principal that owns this process. 0N/A// this method should not be used if to test the status of an otherwise 0N/A// arbitrary process unless it is know that this process has the appropriate 0N/A// privileges to guarantee a result valid. 0N/A // the process does not exist. 0N/A// check if the file system is considered secure for the backing store files 0N/A // check that we have something like "C:\" or "AA:\" 0N/A // we can't get information about the volume, so assume unsafe. 0N/A warning(
"could not get device information for %s: " 0N/A " path = %s: lasterror = %d\n",
0N/A // file system doesn't support ACLs, declare file system unsafe 0N/A warning(
"file system type %s on device %s does not support" 0N/A // file system is compressed, declare file system unsafe 0N/A warning(
"file system type %s on device %s is compressed\n",
0N/A// cleanup stale shared memory resources 0N/A// This method attempts to remove all stale shared memory files in 0N/A// the named user temporary directory. It scans the named directory 0N/A// for files matching the pattern ^$[0-9]*$. For each file found, the 0N/A// process id is extracted from the file name and a test is run to 0N/A// determine if the process is alive. If the process is not alive, 0N/A// any stale file resources are removed. 0N/A // open the user temp directory 0N/A // directory doesn't exist, so there is nothing to cleanup 0N/A // the directory is not secure, don't attempt any cleanup 0N/A // for each entry in the directory that matches the expected file 0N/A // name pattern, determine if the file resources are stale and if 0N/A // so, remove the file resources. Note, instrumented HotSpot processes 0N/A // for this user may start and/or terminate during this search and 0N/A // remove or create new files in this directory. The behavior of this 0N/A // loop under these conditions is dependent upon the implementation of 0N/A // attempt to remove all unexpected files, except "." and ".." 0N/A // we now have a file name that converts to a valid integer 0N/A // that could represent a process id . if this process id 0N/A // matches the current process id or the process is not running, 0N/A // then remove the stale file resources. 0N/A // process liveness is detected by checking the exit status 0N/A // of the process. if the process id is valid and the exit status 0N/A // indicates that it is still running, the file file resources 0N/A // are not removed. If the process id is invalid, or if we don't 0N/A // have permissions to check the process status, or if the process 0N/A // id is valid and the process has terminated, the the file resources 0N/A // are assumed to be stale and are removed. 0N/A // we can only remove the file resources. Any mapped views 0N/A // of the file can only be unmapped by the processes that 0N/A // opened those views and the file mapping object will not 0N/A // get removed until all views are unmapped. 0N/A// create a file mapping object with the requested name, and size 0N/A// from the file represented by the given Handle object 0N/A // Create a file mapping object with the given name. This function 0N/A // will grow the file to the specified size. 0N/A fh,
/* HANDLE file handle for backing store */ 0N/A fsa,
/* LPSECURITY_ATTRIBUTES Not inheritable */ 0N/A name);
/* LPCTSTR name for object */ 0N/A // a stale file mapping object was encountered. This object may be 0N/A // owned by this or some other user and cannot be removed until 0N/A // the other processes either exit or close their mapping objects 0N/A // and/or mapped views of this mapping object. 0N/A// method to free the given security descriptor and the contained 0N/A// access control list. 0N/A // get the access control list from the security descriptor 0N/A // if an ACL existed and it was not a default acl, then it must 0N/A // be an ACL we enlisted. free the resources. 0N/A // free the security descriptor 0N/A// method to free up a security attributes structure and any 0N/A// contained security descriptors and ACL 0N/A // free the contained security descriptor and the ACL 0N/A // free the security attributes structure 0N/A// get the user SID for the process indicated by the process handle 0N/A // get the process token 0N/A // determine the size of the token structured needed to retrieve 0N/A // the user token information from the access token. 0N/A warning(
"GetTokenInformation failure: lasterror = %d," 0N/A // get the user token information 0N/A warning(
"GetTokenInformation failure: lasterror = %d," 0N/A warning(
"GetTokenInformation failure: lasterror = %d," 0N/A // close the access token. 0N/A// structure used to consolidate access control entry information 0N/A// method to add an allow access control entry with the access rights 0N/A// indicated in mask for the principal indicated in SID to the given 0N/A// security descriptor. Much of the DACL handling was adapted from 0N/A// the example provided here: 0N/A // retrieve any existing access control list. 0N/A warning(
"GetSecurityDescriptor failure: lasterror = %d \n",
0N/A // get the size of the DACL 0N/A // GetSecurityDescriptorDacl may return true value for exists (lpbDaclPresent) 0N/A // while oldACL is NULL for some case. 0N/A // compute the size needed for the new ACL 0N/A // initial size of ACL is sum of the following: 0N/A // * size of ACL structure. 0N/A // * size of each ACE structure that ACL is to contain minus the sid 0N/A // sidStart member (DWORD) of the ACE. 0N/A // * length of the SID that each ACE is to contain. 0N/A // create the new ACL 0N/A // copy any existing ACEs from the old ACL (if any) to the new ACL. 0N/A // this is an inherited, allowed ACE; break from loop so we can 0N/A // add the new access allowed, non-inherited ACE in the correct 0N/A // position, immediately following all non-inherited ACEs. 0N/A // determine if the SID of this ACE matches any of the SIDs 0N/A // for which we plan to set ACEs. 0N/A // if there are no SID matches, then add this existing ACE to the new ACL 0N/A // add the passed-in access control entries to the new ACL 0N/A warning(
"AddAccessAllowedAce failure: lasterror = %d \n",
0N/A // now copy the rest of the inherited ACEs from the old ACL 0N/A // picking up at ace_index, where we left off in the 0N/A // previous ace_index loop 0N/A // add the new ACL to the security descriptor. 605N/A // if running on windows 2000 or later, set the automatic inheritance 0N/A "SetSecurityDescriptorControl");
605N/A // We do not want to further propagate inherited DACLs, so making them 0N/A // protected prevents that. 0N/A // Note, the security descriptor maintains a reference to the newACL, not 0N/A // a copy of it. Therefore, the newACL is not freed here. It is freed when 0N/A // the security descriptor containing its reference is freed. 0N/A// method to create a security attributes structure, which contains a 0N/A// security descriptor and an access control list comprised of 0 or more 0N/A// access control entries. The method take an array of ace_data structures 0N/A// that indicate the ACE to be added to the security descriptor. 0N/A// the caller must free the resources associated with the security 0N/A// attributes structure created by this method by calling the 0N/A// free_security_attr() method. 0N/A // allocate space for a security descriptor 0N/A // initialize the security descriptor 0N/A // add the access control entries 0N/A // allocate and initialize the security attributes structure and 0N/A // return it to the caller. 0N/A// method to create a security attributes structure with a restrictive 0N/A// access control list that creates a set access rights for the user/owner 0N/A// of the securable object and a separate set access rights for everyone else. 0N/A// also provides for full access rights for the administrator group. 0N/A// the caller must free the resources associated with the security 0N/A// attributes structure created by this method by calling the 0N/A// free_security_attr() method. 0N/A // initialize the user ace data 0N/A // get the well known SID for BUILTIN\Administrators 0N/A // initialize the ace data for administrator group 0N/A // get the well known SID for the universal Everybody 0N/A // initialize the ace data for everybody else. 0N/A // create a security attributes structure with access control 0N/A // entries as initialized above. 0N/A// method to create the security attributes structure for restricting 0N/A// access to the user temporary directory. 0N/A// the caller must free the resources associated with the security 0N/A// attributes structure created by this method by calling the 0N/A// free_security_attr() method. 0N/A // create full access rights for the user/owner of the directory 0N/A // and read-only access rights for everybody else. This is 0N/A // effectively equivalent to UNIX 755 permissions on a directory. 0N/A// method to create the security attributes structure for restricting 0N/A// access to the shared memory backing store file. 0N/A// the caller must free the resources associated with the security 0N/A// attributes structure created by this method by calling the 0N/A// free_security_attr() method. 0N/A // create extensive access rights for the user/owner of the file 0N/A // and attribute read-only access rights for everybody else. This 0N/A // is effectively equivalent to UNIX 600 permissions on a file. 0N/A// method to create the security attributes structure for restricting 0N/A// access to the name shared memory file mapping object. 0N/A// the caller must free the resources associated with the security 0N/A// attributes structure created by this method by calling the 0N/A// free_security_attr() method. 0N/A // create extensive access rights for the user/owner of the shared 0N/A // memory object and attribute read-only access rights for everybody 0N/A // else. This is effectively equivalent to UNIX 600 permissions on 0N/A // on the shared memory object. 0N/A// make the user specific temporary directory 0N/A // create the directory with the given security attributes 0N/A // The directory already exists and was probably created by another 0N/A // JVM instance. However, this could also be the result of a 0N/A // deliberate symlink. Verify that the existing directory is safe. 0N/A // directory is not secure 0N/A // The administrator should be able to delete this directory. 0N/A // But the directory created by previous version of JVM may not 0N/A // have permission for administrators to delete this directory. 0N/A // So add full permission to the administrator. Also setting new 0N/A // DACLs might fix the corrupted the DACLs. 0N/A warning(
"SetFileSecurity failed for %s directory. lasterror %d \n",
0N/A // free the security attributes structure 0N/A// create the shared memory resources 0N/A// This function creates the shared memory resources. This includes 0N/A// the backing store file and the file mapping shared memory object. 0N/A // create the security attributes for the backing store file 0N/A // create the security attributes for the shared memory object 0N/A // create the user temporary directory 0N/A // could not make/find the directory or the found directory 0N/A // Create the file - the FILE_FLAG_DELETE_ON_CLOSE flag allows the 0N/A // file to be deleted by the last process that closes its handle to 0N/A // the file. This is important as the apis do not allow a terminating 0N/A // JVM being monitored by another process to remove the file name. 0N/A // the FILE_SHARE_DELETE share mode is valid only in winnt 0N/A * open operations allowed 0N/A * create file, if it already 0N/A * exists, overwrite it. 0N/A NULL);
/* HANDLE template file access */ 0N/A // try to create the file mapping 0N/A // closing the file handle here will decrement the reference count 0N/A // on the file. When all processes accessing the file close their 0N/A // handle to it, the reference count will decrement to 0 and the 0N/A // OS will delete the file. These semantics are requested by the 0N/A // FILE_FLAG_DELETE_ON_CLOSE flag in CreateFile call above. 2108N/A // We created the file mapping, but rarely the size of the 2108N/A // backing store file is reported as zero (0) which can cause 2108N/A // failures when trying to use the hsperfdata file. 2108N/A warning(
"Could not get status information from file %s: %s\n",
2108N/A // We could always call FlushFileBuffers() but the Microsoft 2108N/A // docs indicate that it is considered expensive so we only 2108N/A // call it when we observe the size as zero (0). 0N/A // the file has been successfully created and the file mapping 0N/A // object has been created. 0N/A// open the shared memory object for the given vmid. 0N/A // open the file mapping with the requested mode 0N/A FALSE,
/* BOOL inherit flag - Do not allow inherit */ 0N/A warning(
"OpenFileMapping failed for shared memory object %s:" 0N/A// create a named shared memory region 0N/A// On Win32, a named shared memory object has a name space that 0N/A// is independent of the file system name space. Shared memory object, 0N/A// or more precisely, file mapping objects, provide no mechanism to 0N/A// inquire the size of the memory region. There is also no api to 0N/A// enumerate the memory regions for various processes. 0N/A// This implementation utilizes the shared memory name space in parallel 0N/A// with the file system name space. This allows us to determine the 0N/A// size of the shared memory region from the size of the file and it 0N/A// allows us to provide a common, file system based name space for 0N/A// shared memory across platforms. 0N/A // get the name of the user associated with this process 0N/A // construct the name of the user specific temporary directory 0N/A // check that the file system is secure - i.e. it supports ACLs. 0N/A // create the names of the backing store files and for the 0N/A // share memory object. 0N/A // cleanup any stale shared memory resources 0N/A "unexpected PerfMemry region size");
0N/A // create the shared memory resources 0N/A // map the file into the address space 0N/A 0,
/* DWORD High word of offset */ 0N/A 0,
/* DWORD Low word of offset */ 0N/A // clear the shared memory region 4064N/A // it does not go through os api, the operation has to record from here 0N/A// this method deletes the file mapping object. 0N/A // cleanup the persistent shared memory resources. since DestroyJavaVM does 0N/A // not support unloading of the JVM, unmapping of the memory resource is not 0N/A // performed. The memory will be reclaimed by the OS upon termination of all 0N/A // processes mapping the resource. The file mapping handle and the file 0N/A // handle are closed here to expedite the remove of the file by the OS. The 0N/A // file is not removed directly because it was created with 0N/A // FILE_FLAG_DELETE_ON_CLOSE semantics and any attempt to remove it would 0N/A // close the fileMapHandle. the file mapping will still be retained 0N/A // by the OS as long as any other JVM processes has an open file mapping 0N/A // handle or a mapped view of the file. 0N/A // close the file handle. This will decrement the reference count on the 0N/A // backing store file. When the reference count decrements to 0, the OS 0N/A // will delete the file. These semantics apply because the file was 0N/A // created with the FILE_FLAG_DELETE_ON_CLOSE flag. 0N/A// this method determines the size of the shared memory file 0N/A // get the file size 0N/A // on win95/98/me, _stat returns a file size of 0 bytes, but on 0N/A // winnt/2k the appropriate file size is returned. support for 0N/A // the sharable aspects of performance counters was abandonded 0N/A // on the non-nt win32 platforms due to this and other api 0N/A "Could not determine PerfMemory size");
0N/A "Invalid PerfMemory size");
0N/A// this method opens a file mapping object and maps the object 0N/A// into the address space of the process 0N/A "Unsupported access mode");
0N/A "Illegal access mode");
0N/A // if a user name wasn't specified, then find the user name for 0N/A // the owner of the target vm. 0N/A "Could not map vmid to user name");
0N/A // get the names for the resources for the target vm 0N/A // since we don't follow symbolic links when creating the backing 0N/A // store file, we also don't following them when attaching 0N/A "Process not found");
0N/A // copy heap memory to resource memory. the objectname and 0N/A // filename are passed to methods that may throw exceptions. 0N/A // using resource arrays for these names prevents the leaks 0N/A // that would otherwise occur. 0N/A // free the c heap resources that are no longer needed 0N/A // Open the file mapping object with the given name 0N/A // map the entire file into the address space 0N/A fmh,
/* HANDLE Handle of file mapping object */ 0N/A 0,
/* DWORD High word of offset */ 0N/A 0,
/* DWORD Low word of offset */ 0N/A size);
/* DWORD Number of bytes to map */ 0N/A "Could not map PerfMemory");
4064N/A // it does not go through os api, the operation has to record from here 0N/A // File mapping object can be closed at this time without 0N/A // invalidating the mapped view of the file 0N/A// this method unmaps the the mapped view of the the 0N/A// file mapping object. 0N/A // the file mapping object was closed in open_file_mapping() 0N/A // after the file map view was created. We only need to 0N/A // unmap the file view here. 0N/A// create the PerfData memory region in shared memory. 0N/A// release a named, shared memory region 0N/A// create the PerfData memory region 0N/A// This method creates the memory region used to store performance 0N/A// data for the JVM. The memory may be created in standard or 0N/A // do not share the memory for the performance data. 0N/A // creation of the shared memory region failed, attempt 0N/A // to create a contiguous, non-shared memory region instead. 0N/A warning(
"Reverting to non-shared PerfMemory region.\n");
0N/A// delete the PerfData memory region 0N/A// This method deletes the memory region used to store performance 0N/A// data for the JVM. The memory region indicated by the <address, size> 0N/A// tuple will be inaccessible after a call to this method. 0N/A // If user specifies PerfDataSaveFile, it will save the performance data 0N/A // to the specified file name no matter whether PerfDataSaveToFile is specified 0N/A // or not. In other word, -XX:PerfDataSaveFile=.. overrides flag 0N/A // -XX:+PerfDataSaveToFile. 0N/A// attach to the PerfData memory region for another JVM 0N/A// This method returns an <address, size> tuple that points to 0N/A// a memory buffer that is kept reasonably synchronized with 0N/A// the PerfData memory region for the indicated JVM. This 0N/A// buffer may be kept in synchronization via shared memory 0N/A// or some other mechanism that keeps the buffer updated. 0N/A// If the JVM chooses not to support the attachability feature, 0N/A// this method should throw an UnsupportedOperation exception. 0N/A// This implementation utilizes named shared memory to map 0N/A// the indicated process's PerfData memory region into this JVMs 0N/A// detach from the PerfData memory region of another JVM 0N/A// This method detaches the PerfData memory region of another 0N/A// JVM, specified as an <address, size> tuple of a buffer 0N/A// in this process's address space. This method may perform 0N/A// arbitrary actions to accomplish the detachment. The memory 0N/A// region specified by <address, size> will be inaccessible after 0N/A// a call to this method. 0N/A// If the JVM chooses not to support the attachability feature, 0N/A// this method should throw an UnsupportedOperation exception. 0N/A// This implementation utilizes named shared memory to detach 0N/A// the indicated process's PerfData memory region from this 0N/A// process's address space. 0N/A // prevent accidental detachment of this process's PerfMemory region 4064N/A // it does not go through os api, the operation has to record from here