comparison src/os/bsd/vm/perfMemory_bsd.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 f08d439fab8c
children b9a9ed0f8eeb
comparison
equal deleted inserted replaced
6174:74533f63b116 6197:d2a62e0f25eb
124 if (result == OS_ERR) { 124 if (result == OS_ERR) {
125 warning("Could not close %s: %s\n", destfile, strerror(errno)); 125 warning("Could not close %s: %s\n", destfile, strerror(errno));
126 } 126 }
127 } 127 }
128 } 128 }
129 FREE_C_HEAP_ARRAY(char, destfile); 129 FREE_C_HEAP_ARRAY(char, destfile, mtInternal);
130 } 130 }
131 131
132 132
133 // Shared Memory Implementation Details 133 // Shared Memory Implementation Details
134 134
151 static char* get_user_tmp_dir(const char* user) { 151 static char* get_user_tmp_dir(const char* user) {
152 152
153 const char* tmpdir = os::get_temp_directory(); 153 const char* tmpdir = os::get_temp_directory();
154 const char* perfdir = PERFDATA_NAME; 154 const char* perfdir = PERFDATA_NAME;
155 size_t nbytes = strlen(tmpdir) + strlen(perfdir) + strlen(user) + 3; 155 size_t nbytes = strlen(tmpdir) + strlen(perfdir) + strlen(user) + 3;
156 char* dirname = NEW_C_HEAP_ARRAY(char, nbytes); 156 char* dirname = NEW_C_HEAP_ARRAY(char, nbytes, mtInternal);
157 157
158 // construct the path name to user specific tmp directory 158 // construct the path name to user specific tmp directory
159 snprintf(dirname, nbytes, "%s/%s_%s", tmpdir, perfdir, user); 159 snprintf(dirname, nbytes, "%s/%s_%s", tmpdir, perfdir, user);
160 160
161 return dirname; 161 return dirname;
244 // 244 //
245 long bufsize = sysconf(_SC_GETPW_R_SIZE_MAX); 245 long bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
246 if (bufsize == -1) 246 if (bufsize == -1)
247 bufsize = 1024; 247 bufsize = 1024;
248 248
249 char* pwbuf = NEW_C_HEAP_ARRAY(char, bufsize); 249 char* pwbuf = NEW_C_HEAP_ARRAY(char, bufsize, mtInternal);
250 250
251 // POSIX interface to getpwuid_r is used on LINUX 251 // POSIX interface to getpwuid_r is used on LINUX
252 struct passwd* p; 252 struct passwd* p;
253 int result = getpwuid_r(uid, &pwent, pwbuf, (size_t)bufsize, &p); 253 int result = getpwuid_r(uid, &pwent, pwbuf, (size_t)bufsize, &p);
254 254
276 warning("Could not determine user name: %s\n", 276 warning("Could not determine user name: %s\n",
277 p->pw_name == NULL ? "pw_name = NULL" : 277 p->pw_name == NULL ? "pw_name = NULL" :
278 "pw_name zero length"); 278 "pw_name zero length");
279 } 279 }
280 } 280 }
281 FREE_C_HEAP_ARRAY(char, pwbuf); 281 FREE_C_HEAP_ARRAY(char, pwbuf, mtInternal);
282 return NULL; 282 return NULL;
283 } 283 }
284 284
285 char* user_name = NEW_C_HEAP_ARRAY(char, strlen(p->pw_name) + 1); 285 char* user_name = NEW_C_HEAP_ARRAY(char, strlen(p->pw_name) + 1, mtInternal);
286 strcpy(user_name, p->pw_name); 286 strcpy(user_name, p->pw_name);
287 287
288 FREE_C_HEAP_ARRAY(char, pwbuf); 288 FREE_C_HEAP_ARRAY(char, pwbuf, mtInternal);
289 return user_name; 289 return user_name;
290 } 290 }
291 291
292 // return the name of the user that owns the process identified by vmid. 292 // return the name of the user that owns the process identified by vmid.
293 // 293 //
326 // open the directory and check if the file for the given vmid exists. 326 // open the directory and check if the file for the given vmid exists.
327 // The file with the expected name and the latest creation date is used 327 // The file with the expected name and the latest creation date is used
328 // to determine the user name for the process id. 328 // to determine the user name for the process id.
329 // 329 //
330 struct dirent* dentry; 330 struct dirent* dentry;
331 char* tdbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(tmpdirname)); 331 char* tdbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(tmpdirname), mtInternal);
332 errno = 0; 332 errno = 0;
333 while ((dentry = os::readdir(tmpdirp, (struct dirent *)tdbuf)) != NULL) { 333 while ((dentry = os::readdir(tmpdirp, (struct dirent *)tdbuf)) != NULL) {
334 334
335 // check if the directory entry is a hsperfdata file 335 // check if the directory entry is a hsperfdata file
336 if (strncmp(dentry->d_name, PERFDATA_NAME, strlen(PERFDATA_NAME)) != 0) { 336 if (strncmp(dentry->d_name, PERFDATA_NAME, strlen(PERFDATA_NAME)) != 0) {
337 continue; 337 continue;
338 } 338 }
339 339
340 char* usrdir_name = NEW_C_HEAP_ARRAY(char, 340 char* usrdir_name = NEW_C_HEAP_ARRAY(char,
341 strlen(tmpdirname) + strlen(dentry->d_name) + 2); 341 strlen(tmpdirname) + strlen(dentry->d_name) + 2, mtInternal);
342 strcpy(usrdir_name, tmpdirname); 342 strcpy(usrdir_name, tmpdirname);
343 strcat(usrdir_name, "/"); 343 strcat(usrdir_name, "/");
344 strcat(usrdir_name, dentry->d_name); 344 strcat(usrdir_name, dentry->d_name);
345 345
346 DIR* subdirp = os::opendir(usrdir_name); 346 DIR* subdirp = os::opendir(usrdir_name);
347 347
348 if (subdirp == NULL) { 348 if (subdirp == NULL) {
349 FREE_C_HEAP_ARRAY(char, usrdir_name); 349 FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
350 continue; 350 continue;
351 } 351 }
352 352
353 // Since we don't create the backing store files in directories 353 // Since we don't create the backing store files in directories
354 // pointed to by symbolic links, we also don't follow them when 354 // pointed to by symbolic links, we also don't follow them when
355 // looking for the files. We check for a symbolic link after the 355 // looking for the files. We check for a symbolic link after the
356 // call to opendir in order to eliminate a small window where the 356 // call to opendir in order to eliminate a small window where the
357 // symlink can be exploited. 357 // symlink can be exploited.
358 // 358 //
359 if (!is_directory_secure(usrdir_name)) { 359 if (!is_directory_secure(usrdir_name)) {
360 FREE_C_HEAP_ARRAY(char, usrdir_name); 360 FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
361 os::closedir(subdirp); 361 os::closedir(subdirp);
362 continue; 362 continue;
363 } 363 }
364 364
365 struct dirent* udentry; 365 struct dirent* udentry;
366 char* udbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(usrdir_name)); 366 char* udbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(usrdir_name), mtInternal);
367 errno = 0; 367 errno = 0;
368 while ((udentry = os::readdir(subdirp, (struct dirent *)udbuf)) != NULL) { 368 while ((udentry = os::readdir(subdirp, (struct dirent *)udbuf)) != NULL) {
369 369
370 if (filename_to_pid(udentry->d_name) == vmid) { 370 if (filename_to_pid(udentry->d_name) == vmid) {
371 struct stat statbuf; 371 struct stat statbuf;
372 int result; 372 int result;
373 373
374 char* filename = NEW_C_HEAP_ARRAY(char, 374 char* filename = NEW_C_HEAP_ARRAY(char,
375 strlen(usrdir_name) + strlen(udentry->d_name) + 2); 375 strlen(usrdir_name) + strlen(udentry->d_name) + 2, mtInternal);
376 376
377 strcpy(filename, usrdir_name); 377 strcpy(filename, usrdir_name);
378 strcat(filename, "/"); 378 strcat(filename, "/");
379 strcat(filename, udentry->d_name); 379 strcat(filename, udentry->d_name);
380 380
381 // don't follow symbolic links for the file 381 // don't follow symbolic links for the file
382 RESTARTABLE(::lstat(filename, &statbuf), result); 382 RESTARTABLE(::lstat(filename, &statbuf), result);
383 if (result == OS_ERR) { 383 if (result == OS_ERR) {
384 FREE_C_HEAP_ARRAY(char, filename); 384 FREE_C_HEAP_ARRAY(char, filename, mtInternal);
385 continue; 385 continue;
386 } 386 }
387 387
388 // skip over files that are not regular files. 388 // skip over files that are not regular files.
389 if (!S_ISREG(statbuf.st_mode)) { 389 if (!S_ISREG(statbuf.st_mode)) {
390 FREE_C_HEAP_ARRAY(char, filename); 390 FREE_C_HEAP_ARRAY(char, filename, mtInternal);
391 continue; 391 continue;
392 } 392 }
393 393
394 // compare and save filename with latest creation time 394 // compare and save filename with latest creation time
395 if (statbuf.st_size > 0 && statbuf.st_ctime > oldest_ctime) { 395 if (statbuf.st_size > 0 && statbuf.st_ctime > oldest_ctime) {
396 396
397 if (statbuf.st_ctime > oldest_ctime) { 397 if (statbuf.st_ctime > oldest_ctime) {
398 char* user = strchr(dentry->d_name, '_') + 1; 398 char* user = strchr(dentry->d_name, '_') + 1;
399 399
400 if (oldest_user != NULL) FREE_C_HEAP_ARRAY(char, oldest_user); 400 if (oldest_user != NULL) FREE_C_HEAP_ARRAY(char, oldest_user, mtInternal);
401 oldest_user = NEW_C_HEAP_ARRAY(char, strlen(user)+1); 401 oldest_user = NEW_C_HEAP_ARRAY(char, strlen(user)+1, mtInternal);
402 402
403 strcpy(oldest_user, user); 403 strcpy(oldest_user, user);
404 oldest_ctime = statbuf.st_ctime; 404 oldest_ctime = statbuf.st_ctime;
405 } 405 }
406 } 406 }
407 407
408 FREE_C_HEAP_ARRAY(char, filename); 408 FREE_C_HEAP_ARRAY(char, filename, mtInternal);
409 } 409 }
410 } 410 }
411 os::closedir(subdirp); 411 os::closedir(subdirp);
412 FREE_C_HEAP_ARRAY(char, udbuf); 412 FREE_C_HEAP_ARRAY(char, udbuf, mtInternal);
413 FREE_C_HEAP_ARRAY(char, usrdir_name); 413 FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
414 } 414 }
415 os::closedir(tmpdirp); 415 os::closedir(tmpdirp);
416 FREE_C_HEAP_ARRAY(char, tdbuf); 416 FREE_C_HEAP_ARRAY(char, tdbuf, mtInternal);
417 417
418 return(oldest_user); 418 return(oldest_user);
419 } 419 }
420 420
421 // return the name of the user that owns the JVM indicated by the given vmid. 421 // return the name of the user that owns the JVM indicated by the given vmid.
432 static char* get_sharedmem_filename(const char* dirname, int vmid) { 432 static char* get_sharedmem_filename(const char* dirname, int vmid) {
433 433
434 // add 2 for the file separator and a null terminator. 434 // add 2 for the file separator and a null terminator.
435 size_t nbytes = strlen(dirname) + UINT_CHARS + 2; 435 size_t nbytes = strlen(dirname) + UINT_CHARS + 2;
436 436
437 char* name = NEW_C_HEAP_ARRAY(char, nbytes); 437 char* name = NEW_C_HEAP_ARRAY(char, nbytes, mtInternal);
438 snprintf(name, nbytes, "%s/%d", dirname, vmid); 438 snprintf(name, nbytes, "%s/%d", dirname, vmid);
439 439
440 return name; 440 return name;
441 } 441 }
442 442
470 // named directory. 470 // named directory.
471 // 471 //
472 static void remove_file(const char* dirname, const char* filename) { 472 static void remove_file(const char* dirname, const char* filename) {
473 473
474 size_t nbytes = strlen(dirname) + strlen(filename) + 2; 474 size_t nbytes = strlen(dirname) + strlen(filename) + 2;
475 char* path = NEW_C_HEAP_ARRAY(char, nbytes); 475 char* path = NEW_C_HEAP_ARRAY(char, nbytes, mtInternal);
476 476
477 strcpy(path, dirname); 477 strcpy(path, dirname);
478 strcat(path, "/"); 478 strcat(path, "/");
479 strcat(path, filename); 479 strcat(path, filename);
480 480
481 remove_file(path); 481 remove_file(path);
482 482
483 FREE_C_HEAP_ARRAY(char, path); 483 FREE_C_HEAP_ARRAY(char, path, mtInternal);
484 } 484 }
485 485
486 486
487 // cleanup stale shared memory resources 487 // cleanup stale shared memory resources
488 // 488 //
515 // remove or create new files in this directory. The behavior of this 515 // remove or create new files in this directory. The behavior of this
516 // loop under these conditions is dependent upon the implementation of 516 // loop under these conditions is dependent upon the implementation of
517 // opendir/readdir. 517 // opendir/readdir.
518 // 518 //
519 struct dirent* entry; 519 struct dirent* entry;
520 char* dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(dirname)); 520 char* dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(dirname), mtInternal);
521 errno = 0; 521 errno = 0;
522 while ((entry = os::readdir(dirp, (struct dirent *)dbuf)) != NULL) { 522 while ((entry = os::readdir(dirp, (struct dirent *)dbuf)) != NULL) {
523 523
524 pid_t pid = filename_to_pid(entry->d_name); 524 pid_t pid = filename_to_pid(entry->d_name);
525 525
554 remove_file(dirname, entry->d_name); 554 remove_file(dirname, entry->d_name);
555 } 555 }
556 errno = 0; 556 errno = 0;
557 } 557 }
558 os::closedir(dirp); 558 os::closedir(dirp);
559 FREE_C_HEAP_ARRAY(char, dbuf); 559 FREE_C_HEAP_ARRAY(char, dbuf, mtInternal);
560 } 560 }
561 561
562 // make the user specific temporary directory. Returns true if 562 // make the user specific temporary directory. Returns true if
563 // the directory exists and is secure upon return. Returns false 563 // the directory exists and is secure upon return. Returns false
564 // if the directory exists but is either a symlink, is otherwise 564 // if the directory exists but is either a symlink, is otherwise
721 assert(((size > 0) && (size % os::vm_page_size() == 0)), 721 assert(((size > 0) && (size % os::vm_page_size() == 0)),
722 "unexpected PerfMemory region size"); 722 "unexpected PerfMemory region size");
723 723
724 fd = create_sharedmem_resources(dirname, filename, size); 724 fd = create_sharedmem_resources(dirname, filename, size);
725 725
726 FREE_C_HEAP_ARRAY(char, user_name); 726 FREE_C_HEAP_ARRAY(char, user_name, mtInternal);
727 FREE_C_HEAP_ARRAY(char, dirname); 727 FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
728 728
729 if (fd == -1) { 729 if (fd == -1) {
730 FREE_C_HEAP_ARRAY(char, filename); 730 FREE_C_HEAP_ARRAY(char, filename, mtInternal);
731 return NULL; 731 return NULL;
732 } 732 }
733 733
734 mapAddress = (char*)::mmap((char*)0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); 734 mapAddress = (char*)::mmap((char*)0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
735 735
741 if (mapAddress == MAP_FAILED) { 741 if (mapAddress == MAP_FAILED) {
742 if (PrintMiscellaneous && Verbose) { 742 if (PrintMiscellaneous && Verbose) {
743 warning("mmap failed - %s\n", strerror(errno)); 743 warning("mmap failed - %s\n", strerror(errno));
744 } 744 }
745 remove_file(filename); 745 remove_file(filename);
746 FREE_C_HEAP_ARRAY(char, filename); 746 FREE_C_HEAP_ARRAY(char, filename, mtInternal);
747 return NULL; 747 return NULL;
748 } 748 }
749 749
750 // save the file name for use in delete_shared_memory() 750 // save the file name for use in delete_shared_memory()
751 backing_store_file_name = filename; 751 backing_store_file_name = filename;
867 867
868 // since we don't follow symbolic links when creating the backing 868 // since we don't follow symbolic links when creating the backing
869 // store file, we don't follow them when attaching either. 869 // store file, we don't follow them when attaching either.
870 // 870 //
871 if (!is_directory_secure(dirname)) { 871 if (!is_directory_secure(dirname)) {
872 FREE_C_HEAP_ARRAY(char, dirname); 872 FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
873 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), 873 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
874 "Process not found"); 874 "Process not found");
875 } 875 }
876 876
877 char* filename = get_sharedmem_filename(dirname, vmid); 877 char* filename = get_sharedmem_filename(dirname, vmid);
882 // would otherwise occur. 882 // would otherwise occur.
883 char* rfilename = NEW_RESOURCE_ARRAY(char, strlen(filename) + 1); 883 char* rfilename = NEW_RESOURCE_ARRAY(char, strlen(filename) + 1);
884 strcpy(rfilename, filename); 884 strcpy(rfilename, filename);
885 885
886 // free the c heap resources that are no longer needed 886 // free the c heap resources that are no longer needed
887 if (luser != user) FREE_C_HEAP_ARRAY(char, luser); 887 if (luser != user) FREE_C_HEAP_ARRAY(char, luser, mtInternal);
888 FREE_C_HEAP_ARRAY(char, dirname); 888 FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
889 FREE_C_HEAP_ARRAY(char, filename); 889 FREE_C_HEAP_ARRAY(char, filename, mtInternal);
890 890
891 // open the shared memory file for the give vmid 891 // open the shared memory file for the give vmid
892 fd = open_sharedmem_file(rfilename, file_flags, CHECK); 892 fd = open_sharedmem_file(rfilename, file_flags, CHECK);
893 assert(fd != OS_ERR, "unexpected value"); 893 assert(fd != OS_ERR, "unexpected value");
894 894