comparison src/os/solaris/vm/perfMemory_solaris.cpp @ 6197:d2a62e0f25eb

6995781: Native Memory Tracking (Phase 1) 7151532: DCmd for hotspot native memory tracking Summary: Implementation of native memory tracking phase 1, which tracks VM native memory usage, and related DCmd Reviewed-by: acorn, coleenp, fparain
author zgu
date Thu, 28 Jun 2012 17:03:16 -0400
parents f95d63e2154a
children b9a9ed0f8eeb
comparison
equal deleted inserted replaced
6174:74533f63b116 6197:d2a62e0f25eb
126 if (result == OS_ERR) { 126 if (result == OS_ERR) {
127 warning("Could not close %s: %s\n", destfile, strerror(errno)); 127 warning("Could not close %s: %s\n", destfile, strerror(errno));
128 } 128 }
129 } 129 }
130 } 130 }
131 FREE_C_HEAP_ARRAY(char, destfile); 131 FREE_C_HEAP_ARRAY(char, destfile, mtInternal);
132 } 132 }
133 133
134 134
135 // Shared Memory Implementation Details 135 // Shared Memory Implementation Details
136 136
153 static char* get_user_tmp_dir(const char* user) { 153 static char* get_user_tmp_dir(const char* user) {
154 154
155 const char* tmpdir = os::get_temp_directory(); 155 const char* tmpdir = os::get_temp_directory();
156 const char* perfdir = PERFDATA_NAME; 156 const char* perfdir = PERFDATA_NAME;
157 size_t nbytes = strlen(tmpdir) + strlen(perfdir) + strlen(user) + 3; 157 size_t nbytes = strlen(tmpdir) + strlen(perfdir) + strlen(user) + 3;
158 char* dirname = NEW_C_HEAP_ARRAY(char, nbytes); 158 char* dirname = NEW_C_HEAP_ARRAY(char, nbytes, mtInternal);
159 159
160 // construct the path name to user specific tmp directory 160 // construct the path name to user specific tmp directory
161 snprintf(dirname, nbytes, "%s/%s_%s", tmpdir, perfdir, user); 161 snprintf(dirname, nbytes, "%s/%s_%s", tmpdir, perfdir, user);
162 162
163 return dirname; 163 return dirname;
246 // 246 //
247 long bufsize = sysconf(_SC_GETPW_R_SIZE_MAX); 247 long bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
248 if (bufsize == -1) 248 if (bufsize == -1)
249 bufsize = 1024; 249 bufsize = 1024;
250 250
251 char* pwbuf = NEW_C_HEAP_ARRAY(char, bufsize); 251 char* pwbuf = NEW_C_HEAP_ARRAY(char, bufsize, mtInternal);
252 252
253 #ifdef _GNU_SOURCE 253 #ifdef _GNU_SOURCE
254 struct passwd* p = NULL; 254 struct passwd* p = NULL;
255 int result = getpwuid_r(uid, &pwent, pwbuf, (size_t)bufsize, &p); 255 int result = getpwuid_r(uid, &pwent, pwbuf, (size_t)bufsize, &p);
256 #else // _GNU_SOURCE 256 #else // _GNU_SOURCE
267 warning("Could not determine user name: %s\n", 267 warning("Could not determine user name: %s\n",
268 p->pw_name == NULL ? "pw_name = NULL" : 268 p->pw_name == NULL ? "pw_name = NULL" :
269 "pw_name zero length"); 269 "pw_name zero length");
270 } 270 }
271 } 271 }
272 FREE_C_HEAP_ARRAY(char, pwbuf); 272 FREE_C_HEAP_ARRAY(char, pwbuf, mtInternal);
273 return NULL; 273 return NULL;
274 } 274 }
275 275
276 char* user_name = NEW_C_HEAP_ARRAY(char, strlen(p->pw_name) + 1); 276 char* user_name = NEW_C_HEAP_ARRAY(char, strlen(p->pw_name) + 1, mtInternal);
277 strcpy(user_name, p->pw_name); 277 strcpy(user_name, p->pw_name);
278 278
279 FREE_C_HEAP_ARRAY(char, pwbuf); 279 FREE_C_HEAP_ARRAY(char, pwbuf, mtInternal);
280 return user_name; 280 return user_name;
281 } 281 }
282 282
283 // return the name of the user that owns the process identified by vmid. 283 // return the name of the user that owns the process identified by vmid.
284 // 284 //
317 // open the directory and check if the file for the given vmid exists. 317 // open the directory and check if the file for the given vmid exists.
318 // The file with the expected name and the latest creation date is used 318 // The file with the expected name and the latest creation date is used
319 // to determine the user name for the process id. 319 // to determine the user name for the process id.
320 // 320 //
321 struct dirent* dentry; 321 struct dirent* dentry;
322 char* tdbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(tmpdirname)); 322 char* tdbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(tmpdirname), mtInternal);
323 errno = 0; 323 errno = 0;
324 while ((dentry = os::readdir(tmpdirp, (struct dirent *)tdbuf)) != NULL) { 324 while ((dentry = os::readdir(tmpdirp, (struct dirent *)tdbuf)) != NULL) {
325 325
326 // check if the directory entry is a hsperfdata file 326 // check if the directory entry is a hsperfdata file
327 if (strncmp(dentry->d_name, PERFDATA_NAME, strlen(PERFDATA_NAME)) != 0) { 327 if (strncmp(dentry->d_name, PERFDATA_NAME, strlen(PERFDATA_NAME)) != 0) {
328 continue; 328 continue;
329 } 329 }
330 330
331 char* usrdir_name = NEW_C_HEAP_ARRAY(char, 331 char* usrdir_name = NEW_C_HEAP_ARRAY(char,
332 strlen(tmpdirname) + strlen(dentry->d_name) + 2); 332 strlen(tmpdirname) + strlen(dentry->d_name) + 2, mtInternal);
333 strcpy(usrdir_name, tmpdirname); 333 strcpy(usrdir_name, tmpdirname);
334 strcat(usrdir_name, "/"); 334 strcat(usrdir_name, "/");
335 strcat(usrdir_name, dentry->d_name); 335 strcat(usrdir_name, dentry->d_name);
336 336
337 DIR* subdirp = os::opendir(usrdir_name); 337 DIR* subdirp = os::opendir(usrdir_name);
338 338
339 if (subdirp == NULL) { 339 if (subdirp == NULL) {
340 FREE_C_HEAP_ARRAY(char, usrdir_name); 340 FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
341 continue; 341 continue;
342 } 342 }
343 343
344 // Since we don't create the backing store files in directories 344 // Since we don't create the backing store files in directories
345 // pointed to by symbolic links, we also don't follow them when 345 // pointed to by symbolic links, we also don't follow them when
346 // looking for the files. We check for a symbolic link after the 346 // looking for the files. We check for a symbolic link after the
347 // call to opendir in order to eliminate a small window where the 347 // call to opendir in order to eliminate a small window where the
348 // symlink can be exploited. 348 // symlink can be exploited.
349 // 349 //
350 if (!is_directory_secure(usrdir_name)) { 350 if (!is_directory_secure(usrdir_name)) {
351 FREE_C_HEAP_ARRAY(char, usrdir_name); 351 FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
352 os::closedir(subdirp); 352 os::closedir(subdirp);
353 continue; 353 continue;
354 } 354 }
355 355
356 struct dirent* udentry; 356 struct dirent* udentry;
357 char* udbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(usrdir_name)); 357 char* udbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(usrdir_name), mtInternal);
358 errno = 0; 358 errno = 0;
359 while ((udentry = os::readdir(subdirp, (struct dirent *)udbuf)) != NULL) { 359 while ((udentry = os::readdir(subdirp, (struct dirent *)udbuf)) != NULL) {
360 360
361 if (filename_to_pid(udentry->d_name) == vmid) { 361 if (filename_to_pid(udentry->d_name) == vmid) {
362 struct stat statbuf; 362 struct stat statbuf;
363 int result; 363 int result;
364 364
365 char* filename = NEW_C_HEAP_ARRAY(char, 365 char* filename = NEW_C_HEAP_ARRAY(char,
366 strlen(usrdir_name) + strlen(udentry->d_name) + 2); 366 strlen(usrdir_name) + strlen(udentry->d_name) + 2, mtInternal);
367 367
368 strcpy(filename, usrdir_name); 368 strcpy(filename, usrdir_name);
369 strcat(filename, "/"); 369 strcat(filename, "/");
370 strcat(filename, udentry->d_name); 370 strcat(filename, udentry->d_name);
371 371
372 // don't follow symbolic links for the file 372 // don't follow symbolic links for the file
373 RESTARTABLE(::lstat(filename, &statbuf), result); 373 RESTARTABLE(::lstat(filename, &statbuf), result);
374 if (result == OS_ERR) { 374 if (result == OS_ERR) {
375 FREE_C_HEAP_ARRAY(char, filename); 375 FREE_C_HEAP_ARRAY(char, filename, mtInternal);
376 continue; 376 continue;
377 } 377 }
378 378
379 // skip over files that are not regular files. 379 // skip over files that are not regular files.
380 if (!S_ISREG(statbuf.st_mode)) { 380 if (!S_ISREG(statbuf.st_mode)) {
381 FREE_C_HEAP_ARRAY(char, filename); 381 FREE_C_HEAP_ARRAY(char, filename, mtInternal);
382 continue; 382 continue;
383 } 383 }
384 384
385 // compare and save filename with latest creation time 385 // compare and save filename with latest creation time
386 if (statbuf.st_size > 0 && statbuf.st_ctime > oldest_ctime) { 386 if (statbuf.st_size > 0 && statbuf.st_ctime > oldest_ctime) {
387 387
388 if (statbuf.st_ctime > oldest_ctime) { 388 if (statbuf.st_ctime > oldest_ctime) {
389 char* user = strchr(dentry->d_name, '_') + 1; 389 char* user = strchr(dentry->d_name, '_') + 1;
390 390
391 if (oldest_user != NULL) FREE_C_HEAP_ARRAY(char, oldest_user); 391 if (oldest_user != NULL) FREE_C_HEAP_ARRAY(char, oldest_user, mtInternal);
392 oldest_user = NEW_C_HEAP_ARRAY(char, strlen(user)+1); 392 oldest_user = NEW_C_HEAP_ARRAY(char, strlen(user)+1, mtInternal);
393 393
394 strcpy(oldest_user, user); 394 strcpy(oldest_user, user);
395 oldest_ctime = statbuf.st_ctime; 395 oldest_ctime = statbuf.st_ctime;
396 } 396 }
397 } 397 }
398 398
399 FREE_C_HEAP_ARRAY(char, filename); 399 FREE_C_HEAP_ARRAY(char, filename, mtInternal);
400 } 400 }
401 } 401 }
402 os::closedir(subdirp); 402 os::closedir(subdirp);
403 FREE_C_HEAP_ARRAY(char, udbuf); 403 FREE_C_HEAP_ARRAY(char, udbuf, mtInternal);
404 FREE_C_HEAP_ARRAY(char, usrdir_name); 404 FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
405 } 405 }
406 os::closedir(tmpdirp); 406 os::closedir(tmpdirp);
407 FREE_C_HEAP_ARRAY(char, tdbuf); 407 FREE_C_HEAP_ARRAY(char, tdbuf, mtInternal);
408 408
409 return(oldest_user); 409 return(oldest_user);
410 } 410 }
411 411
412 // return the name of the user that owns the JVM indicated by the given vmid. 412 // return the name of the user that owns the JVM indicated by the given vmid.
469 static char* get_sharedmem_filename(const char* dirname, int vmid) { 469 static char* get_sharedmem_filename(const char* dirname, int vmid) {
470 470
471 // add 2 for the file separator and a NULL terminator. 471 // add 2 for the file separator and a NULL terminator.
472 size_t nbytes = strlen(dirname) + UINT_CHARS + 2; 472 size_t nbytes = strlen(dirname) + UINT_CHARS + 2;
473 473
474 char* name = NEW_C_HEAP_ARRAY(char, nbytes); 474 char* name = NEW_C_HEAP_ARRAY(char, nbytes, mtInternal);
475 snprintf(name, nbytes, "%s/%d", dirname, vmid); 475 snprintf(name, nbytes, "%s/%d", dirname, vmid);
476 476
477 return name; 477 return name;
478 } 478 }
479 479
507 // named directory. 507 // named directory.
508 // 508 //
509 static void remove_file(const char* dirname, const char* filename) { 509 static void remove_file(const char* dirname, const char* filename) {
510 510
511 size_t nbytes = strlen(dirname) + strlen(filename) + 2; 511 size_t nbytes = strlen(dirname) + strlen(filename) + 2;
512 char* path = NEW_C_HEAP_ARRAY(char, nbytes); 512 char* path = NEW_C_HEAP_ARRAY(char, nbytes, mtInternal);
513 513
514 strcpy(path, dirname); 514 strcpy(path, dirname);
515 strcat(path, "/"); 515 strcat(path, "/");
516 strcat(path, filename); 516 strcat(path, filename);
517 517
518 remove_file(path); 518 remove_file(path);
519 519
520 FREE_C_HEAP_ARRAY(char, path); 520 FREE_C_HEAP_ARRAY(char, path, mtInternal);
521 } 521 }
522 522
523 523
524 // cleanup stale shared memory resources 524 // cleanup stale shared memory resources
525 // 525 //
552 // remove or create new files in this directory. The behavior of this 552 // remove or create new files in this directory. The behavior of this
553 // loop under these conditions is dependent upon the implementation of 553 // loop under these conditions is dependent upon the implementation of
554 // opendir/readdir. 554 // opendir/readdir.
555 // 555 //
556 struct dirent* entry; 556 struct dirent* entry;
557 char* dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(dirname)); 557 char* dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(dirname), mtInternal);
558 errno = 0; 558 errno = 0;
559 while ((entry = os::readdir(dirp, (struct dirent *)dbuf)) != NULL) { 559 while ((entry = os::readdir(dirp, (struct dirent *)dbuf)) != NULL) {
560 560
561 pid_t pid = filename_to_pid(entry->d_name); 561 pid_t pid = filename_to_pid(entry->d_name);
562 562
591 remove_file(dirname, entry->d_name); 591 remove_file(dirname, entry->d_name);
592 } 592 }
593 errno = 0; 593 errno = 0;
594 } 594 }
595 os::closedir(dirp); 595 os::closedir(dirp);
596 FREE_C_HEAP_ARRAY(char, dbuf); 596 FREE_C_HEAP_ARRAY(char, dbuf, mtInternal);
597 } 597 }
598 598
599 // make the user specific temporary directory. Returns true if 599 // make the user specific temporary directory. Returns true if
600 // the directory exists and is secure upon return. Returns false 600 // the directory exists and is secure upon return. Returns false
601 // if the directory exists but is either a symlink, is otherwise 601 // if the directory exists but is either a symlink, is otherwise
736 assert(((size > 0) && (size % os::vm_page_size() == 0)), 736 assert(((size > 0) && (size % os::vm_page_size() == 0)),
737 "unexpected PerfMemory region size"); 737 "unexpected PerfMemory region size");
738 738
739 fd = create_sharedmem_resources(dirname, filename, size); 739 fd = create_sharedmem_resources(dirname, filename, size);
740 740
741 FREE_C_HEAP_ARRAY(char, user_name); 741 FREE_C_HEAP_ARRAY(char, user_name, mtInternal);
742 FREE_C_HEAP_ARRAY(char, dirname); 742 FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
743 743
744 if (fd == -1) { 744 if (fd == -1) {
745 FREE_C_HEAP_ARRAY(char, filename); 745 FREE_C_HEAP_ARRAY(char, filename, mtInternal);
746 return NULL; 746 return NULL;
747 } 747 }
748 748
749 mapAddress = (char*)::mmap((char*)0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); 749 mapAddress = (char*)::mmap((char*)0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
750 750
756 if (mapAddress == MAP_FAILED) { 756 if (mapAddress == MAP_FAILED) {
757 if (PrintMiscellaneous && Verbose) { 757 if (PrintMiscellaneous && Verbose) {
758 warning("mmap failed - %s\n", strerror(errno)); 758 warning("mmap failed - %s\n", strerror(errno));
759 } 759 }
760 remove_file(filename); 760 remove_file(filename);
761 FREE_C_HEAP_ARRAY(char, filename); 761 FREE_C_HEAP_ARRAY(char, filename, mtInternal);
762 return NULL; 762 return NULL;
763 } 763 }
764 764
765 // save the file name for use in delete_shared_memory() 765 // save the file name for use in delete_shared_memory()
766 backing_store_file_name = filename; 766 backing_store_file_name = filename;
882 882
883 // since we don't follow symbolic links when creating the backing 883 // since we don't follow symbolic links when creating the backing
884 // store file, we don't follow them when attaching either. 884 // store file, we don't follow them when attaching either.
885 // 885 //
886 if (!is_directory_secure(dirname)) { 886 if (!is_directory_secure(dirname)) {
887 FREE_C_HEAP_ARRAY(char, dirname); 887 FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
888 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), 888 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
889 "Process not found"); 889 "Process not found");
890 } 890 }
891 891
892 char* filename = get_sharedmem_filename(dirname, vmid); 892 char* filename = get_sharedmem_filename(dirname, vmid);
897 // would otherwise occur. 897 // would otherwise occur.
898 char* rfilename = NEW_RESOURCE_ARRAY(char, strlen(filename) + 1); 898 char* rfilename = NEW_RESOURCE_ARRAY(char, strlen(filename) + 1);
899 strcpy(rfilename, filename); 899 strcpy(rfilename, filename);
900 900
901 // free the c heap resources that are no longer needed 901 // free the c heap resources that are no longer needed
902 if (luser != user) FREE_C_HEAP_ARRAY(char, luser); 902 if (luser != user) FREE_C_HEAP_ARRAY(char, luser, mtInternal);
903 FREE_C_HEAP_ARRAY(char, dirname); 903 FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
904 FREE_C_HEAP_ARRAY(char, filename); 904 FREE_C_HEAP_ARRAY(char, filename, mtInternal);
905 905
906 // open the shared memory file for the give vmid 906 // open the shared memory file for the give vmid
907 fd = open_sharedmem_file(rfilename, file_flags, CHECK); 907 fd = open_sharedmem_file(rfilename, file_flags, CHECK);
908 assert(fd != OS_ERR, "unexpected value"); 908 assert(fd != OS_ERR, "unexpected value");
909 909