Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(59)

Side by Side Diff: base/process_util_posix.cc

Issue 10411047: Type profiler by intercepting 'new' and 'delete' expressions. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: upload again Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <dirent.h> 5 #include <dirent.h>
6 #include <errno.h> 6 #include <errno.h>
7 #include <fcntl.h> 7 #include <fcntl.h>
8 #include <signal.h> 8 #include <signal.h>
9 #include <stdlib.h> 9 #include <stdlib.h>
10 #include <sys/resource.h> 10 #include <sys/resource.h>
(...skipping 15 matching lines...) Expand all
26 #include "base/files/dir_reader_posix.h" 26 #include "base/files/dir_reader_posix.h"
27 #include "base/logging.h" 27 #include "base/logging.h"
28 #include "base/memory/scoped_ptr.h" 28 #include "base/memory/scoped_ptr.h"
29 #include "base/process_util.h" 29 #include "base/process_util.h"
30 #include "base/stringprintf.h" 30 #include "base/stringprintf.h"
31 #include "base/synchronization/waitable_event.h" 31 #include "base/synchronization/waitable_event.h"
32 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" 32 #include "base/third_party/dynamic_annotations/dynamic_annotations.h"
33 #include "base/threading/platform_thread.h" 33 #include "base/threading/platform_thread.h"
34 #include "base/threading/thread_restrictions.h" 34 #include "base/threading/thread_restrictions.h"
35 35
36 // TODO(dmikurube): Consider always calling {Suspend|Resume}AllocatedType...,
37 // and make them empty functions when !USE_ALLOCATED_TYPE.
38 // This is a temporary comment which should be removed when landing.
39 #ifdef USE_ALLOCATED_TYPE
40 #include "base/allocator/allocated_type_tcmalloc.h"
41 #endif
42
36 #if defined(OS_CHROMEOS) 43 #if defined(OS_CHROMEOS)
37 #include <sys/ioctl.h> 44 #include <sys/ioctl.h>
38 #endif 45 #endif
39 46
40 #if defined(OS_FREEBSD) 47 #if defined(OS_FREEBSD)
41 #include <sys/event.h> 48 #include <sys/event.h>
42 #include <sys/ucontext.h> 49 #include <sys/ucontext.h>
43 #endif 50 #endif
44 51
45 #if defined(OS_MACOSX) 52 #if defined(OS_MACOSX)
(...skipping 588 matching lines...) Expand 10 before | Expand all | Expand 10 after
634 if (options.new_process_group) { 641 if (options.new_process_group) {
635 // Instead of inheriting the process group ID of the parent, the child 642 // Instead of inheriting the process group ID of the parent, the child
636 // starts off a new process group with pgid equal to its process ID. 643 // starts off a new process group with pgid equal to its process ID.
637 if (setpgid(0, 0) < 0) { 644 if (setpgid(0, 0) < 0) {
638 RAW_LOG(ERROR, "setpgid failed"); 645 RAW_LOG(ERROR, "setpgid failed");
639 _exit(127); 646 _exit(127);
640 } 647 }
641 } 648 }
642 649
643 if (options.maximize_rlimits) { 650 if (options.maximize_rlimits) {
651 #ifdef USE_ALLOCATED_TYPE
652 SuspendAllocatedTypeIntercept();
653 #endif
644 // Some resource limits need to be maximal in this child. 654 // Some resource limits need to be maximal in this child.
645 std::set<int>::const_iterator resource; 655 std::set<int>::const_iterator resource;
646 for (resource = options.maximize_rlimits->begin(); 656 for (resource = options.maximize_rlimits->begin();
647 resource != options.maximize_rlimits->end(); 657 resource != options.maximize_rlimits->end();
648 ++resource) { 658 ++resource) {
649 struct rlimit limit; 659 struct rlimit limit;
650 if (getrlimit(*resource, &limit) < 0) { 660 if (getrlimit(*resource, &limit) < 0) {
651 RAW_LOG(WARNING, "getrlimit failed"); 661 RAW_LOG(WARNING, "getrlimit failed");
652 } else if (limit.rlim_cur < limit.rlim_max) { 662 } else if (limit.rlim_cur < limit.rlim_max) {
653 limit.rlim_cur = limit.rlim_max; 663 limit.rlim_cur = limit.rlim_max;
654 if (setrlimit(*resource, &limit) < 0) { 664 if (setrlimit(*resource, &limit) < 0) {
655 RAW_LOG(WARNING, "setrlimit failed"); 665 RAW_LOG(WARNING, "setrlimit failed");
656 } 666 }
657 } 667 }
658 } 668 }
669 #ifdef USE_ALLOCATED_TYPE
670 ResumeAllocatedTypeIntercept();
671 #endif
659 } 672 }
660 673
661 #if defined(OS_MACOSX) 674 #if defined(OS_MACOSX)
662 RestoreDefaultExceptionHandler(); 675 RestoreDefaultExceptionHandler();
663 #endif // defined(OS_MACOSX) 676 #endif // defined(OS_MACOSX)
664 677
665 ResetChildSignalHandlersToDefaults(); 678 ResetChildSignalHandlersToDefaults();
666 679
667 #if defined(OS_MACOSX) 680 #if defined(OS_MACOSX)
668 if (options.synchronize) { 681 if (options.synchronize) {
(...skipping 22 matching lines...) Expand all
691 ioctl(options.ctrl_terminal_fd, TIOCSCTTY, NULL)) == -1) { 704 ioctl(options.ctrl_terminal_fd, TIOCSCTTY, NULL)) == -1) {
692 RAW_LOG(WARNING, "ioctl(TIOCSCTTY), ctrl terminal not set"); 705 RAW_LOG(WARNING, "ioctl(TIOCSCTTY), ctrl terminal not set");
693 } 706 }
694 } else { 707 } else {
695 RAW_LOG(WARNING, "setsid failed, ctrl terminal not set"); 708 RAW_LOG(WARNING, "setsid failed, ctrl terminal not set");
696 } 709 }
697 } 710 }
698 #endif // defined(OS_CHROMEOS) 711 #endif // defined(OS_CHROMEOS)
699 712
700 if (options.fds_to_remap) { 713 if (options.fds_to_remap) {
714 #ifdef USE_ALLOCATED_TYPE
715 SuspendAllocatedTypeIntercept();
716 #endif
701 for (FileHandleMappingVector::const_iterator 717 for (FileHandleMappingVector::const_iterator
702 it = options.fds_to_remap->begin(); 718 it = options.fds_to_remap->begin();
703 it != options.fds_to_remap->end(); ++it) { 719 it != options.fds_to_remap->end(); ++it) {
704 fd_shuffle1.push_back(InjectionArc(it->first, it->second, false)); 720 fd_shuffle1.push_back(InjectionArc(it->first, it->second, false));
705 fd_shuffle2.push_back(InjectionArc(it->first, it->second, false)); 721 fd_shuffle2.push_back(InjectionArc(it->first, it->second, false));
706 } 722 }
723 #ifdef USE_ALLOCATED_TYPE
724 ResumeAllocatedTypeIntercept();
725 #endif
707 } 726 }
708 727
709 #if defined(OS_MACOSX) 728 #if defined(OS_MACOSX)
710 if (options.synchronize) { 729 if (options.synchronize) {
730 #ifdef USE_ALLOCATED_TYPE
731 SuspendAllocatedTypeIntercept();
732 #endif
711 // Remap the read side of the synchronization pipe back onto itself, 733 // Remap the read side of the synchronization pipe back onto itself,
712 // ensuring that it won't be closed by CloseSuperfluousFds. 734 // ensuring that it won't be closed by CloseSuperfluousFds.
713 int keep_fd = *synchronization_read_fd.get(); 735 int keep_fd = *synchronization_read_fd.get();
714 fd_shuffle1.push_back(InjectionArc(keep_fd, keep_fd, false)); 736 fd_shuffle1.push_back(InjectionArc(keep_fd, keep_fd, false));
715 fd_shuffle2.push_back(InjectionArc(keep_fd, keep_fd, false)); 737 fd_shuffle2.push_back(InjectionArc(keep_fd, keep_fd, false));
738 #ifdef USE_ALLOCATED_TYPE
739 ResumeAllocatedTypeIntercept();
740 #endif
716 } 741 }
717 #endif // defined(OS_MACOSX) 742 #endif // defined(OS_MACOSX)
718 743
719 if (options.environ) 744 if (options.environ)
720 SetEnvironment(new_environ.get()); 745 SetEnvironment(new_environ.get());
721 746
747 #ifdef USE_ALLOCATED_TYPE
748 SuspendAllocatedTypeIntercept();
749 #endif
722 // fd_shuffle1 is mutated by this call because it cannot malloc. 750 // fd_shuffle1 is mutated by this call because it cannot malloc.
723 if (!ShuffleFileDescriptors(&fd_shuffle1)) 751 if (!ShuffleFileDescriptors(&fd_shuffle1)) {
752 #ifdef USE_ALLOCATED_TYPE
753 ResumeAllocatedTypeIntercept();
754 #endif
724 _exit(127); 755 _exit(127);
756 }
725 757
726 CloseSuperfluousFds(fd_shuffle2); 758 CloseSuperfluousFds(fd_shuffle2);
759 #ifdef USE_ALLOCATED_TYPE
760 ResumeAllocatedTypeIntercept();
761 #endif
727 762
728 #if defined(OS_MACOSX) 763 #if defined(OS_MACOSX)
729 if (options.synchronize) { 764 if (options.synchronize) {
730 // Do a blocking read to wait until the parent says it's OK to proceed. 765 // Do a blocking read to wait until the parent says it's OK to proceed.
731 // The byte that's read here is written by LaunchSynchronize. 766 // The byte that's read here is written by LaunchSynchronize.
732 char read_char; 767 char read_char;
733 int read_result = 768 int read_result =
734 HANDLE_EINTR(read(*synchronization_read_fd.get(), &read_char, 1)); 769 HANDLE_EINTR(read(*synchronization_read_fd.get(), &read_char, 1));
735 if (read_result != 1) { 770 if (read_result != 1) {
736 RAW_LOG(ERROR, "LaunchProcess: synchronization read: error"); 771 RAW_LOG(ERROR, "LaunchProcess: synchronization read: error");
737 _exit(127); 772 _exit(127);
738 } 773 }
739 774
740 // The pipe is no longer useful. Don't let it live on in the new process 775 // The pipe is no longer useful. Don't let it live on in the new process
741 // after exec. 776 // after exec.
742 synchronization_read_fd.reset(); // closes synchronization_pipe_fds[0] 777 synchronization_read_fd.reset(); // closes synchronization_pipe_fds[0]
743 } 778 }
744 #endif // defined(OS_MACOSX) 779 #endif // defined(OS_MACOSX)
745 780
781 #ifdef USE_ALLOCATED_TYPE
782 SuspendAllocatedTypeIntercept();
783 #endif
746 for (size_t i = 0; i < argv.size(); i++) 784 for (size_t i = 0; i < argv.size(); i++)
747 argv_cstr[i] = const_cast<char*>(argv[i].c_str()); 785 argv_cstr[i] = const_cast<char*>(argv[i].c_str());
748 argv_cstr[argv.size()] = NULL; 786 argv_cstr[argv.size()] = NULL;
787 #ifdef USE_ALLOCATED_TYPE
788 // TODO(dmikurube): Consider removing it. It's just befor exec.
789 // This is a temporary comment which should be removed when landing.
790 ResumeAllocatedTypeIntercept();
791 #endif
749 execvp(argv_cstr[0], argv_cstr.get()); 792 execvp(argv_cstr[0], argv_cstr.get());
750 793
751 RAW_LOG(ERROR, "LaunchProcess: failed to execvp:"); 794 RAW_LOG(ERROR, "LaunchProcess: failed to execvp:");
752 RAW_LOG(ERROR, argv_cstr[0]); 795 RAW_LOG(ERROR, argv_cstr[0]);
753 _exit(127); 796 _exit(127);
754 } else { 797 } else {
755 // Parent process 798 // Parent process
756 if (options.wait) { 799 if (options.wait) {
757 // While this isn't strictly disk IO, waiting for another process to 800 // While this isn't strictly disk IO, waiting for another process to
758 // finish is the sort of thing ThreadRestrictions is trying to prevent. 801 // finish is the sort of thing ThreadRestrictions is trying to prevent.
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after
1101 1144
1102 // Obscure fork() rule: in the child, if you don't end up doing exec*(), 1145 // Obscure fork() rule: in the child, if you don't end up doing exec*(),
1103 // you call _exit() instead of exit(). This is because _exit() does not 1146 // you call _exit() instead of exit(). This is because _exit() does not
1104 // call any previously-registered (in the parent) exit handlers, which 1147 // call any previously-registered (in the parent) exit handlers, which
1105 // might do things like block waiting for threads that don't even exist 1148 // might do things like block waiting for threads that don't even exist
1106 // in the child. 1149 // in the child.
1107 int dev_null = open("/dev/null", O_WRONLY); 1150 int dev_null = open("/dev/null", O_WRONLY);
1108 if (dev_null < 0) 1151 if (dev_null < 0)
1109 _exit(127); 1152 _exit(127);
1110 1153
1154 #ifdef USE_ALLOCATED_TYPE
1155 SuspendAllocatedTypeIntercept();
1156 #endif
1111 fd_shuffle1.push_back(InjectionArc(pipe_fd[1], STDOUT_FILENO, true)); 1157 fd_shuffle1.push_back(InjectionArc(pipe_fd[1], STDOUT_FILENO, true));
1112 fd_shuffle1.push_back(InjectionArc(dev_null, STDERR_FILENO, true)); 1158 fd_shuffle1.push_back(InjectionArc(dev_null, STDERR_FILENO, true));
1113 fd_shuffle1.push_back(InjectionArc(dev_null, STDIN_FILENO, true)); 1159 fd_shuffle1.push_back(InjectionArc(dev_null, STDIN_FILENO, true));
1114 // Adding another element here? Remeber to increase the argument to 1160 // Adding another element here? Remeber to increase the argument to
1115 // reserve(), above. 1161 // reserve(), above.
1116 1162
1117 std::copy(fd_shuffle1.begin(), fd_shuffle1.end(), 1163 std::copy(fd_shuffle1.begin(), fd_shuffle1.end(),
1118 std::back_inserter(fd_shuffle2)); 1164 std::back_inserter(fd_shuffle2));
1119 1165
1120 if (!ShuffleFileDescriptors(&fd_shuffle1)) 1166 if (!ShuffleFileDescriptors(&fd_shuffle1)) {
1167 #ifdef USE_ALLOCATED_TYPE
1168 ResumeAllocatedTypeIntercept();
1169 #endif
1121 _exit(127); 1170 _exit(127);
1171 }
1122 1172
1123 CloseSuperfluousFds(fd_shuffle2); 1173 CloseSuperfluousFds(fd_shuffle2);
1124 1174
1125 for (size_t i = 0; i < argv.size(); i++) 1175 for (size_t i = 0; i < argv.size(); i++)
1126 argv_cstr[i] = const_cast<char*>(argv[i].c_str()); 1176 argv_cstr[i] = const_cast<char*>(argv[i].c_str());
1127 argv_cstr[argv.size()] = NULL; 1177 argv_cstr[argv.size()] = NULL;
1178 #ifdef USE_ALLOCATED_TYPE
1179 // TODO(dmikurube): Consider removing it. It's just befor exec.
1180 // This is a temporary comment which should be removed when landing.
1181 ResumeAllocatedTypeIntercept();
1182 #endif
1128 if (do_search_path) 1183 if (do_search_path)
1129 execvp(argv_cstr[0], argv_cstr.get()); 1184 execvp(argv_cstr[0], argv_cstr.get());
1130 else 1185 else
1131 execve(argv_cstr[0], argv_cstr.get(), envp); 1186 execve(argv_cstr[0], argv_cstr.get(), envp);
1132 _exit(127); 1187 _exit(127);
1133 } 1188 }
1134 default: // parent 1189 default: // parent
1135 { 1190 {
1136 // Close our writing end of pipe now. Otherwise later read would not 1191 // Close our writing end of pipe now. Otherwise later read would not
1137 // be able to detect end of child's output (in theory we could still 1192 // be able to detect end of child's output (in theory we could still
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
1328 if (IsChildDead(process)) 1383 if (IsChildDead(process))
1329 return; 1384 return;
1330 1385
1331 BackgroundReaper* reaper = new BackgroundReaper(process, 0); 1386 BackgroundReaper* reaper = new BackgroundReaper(process, 0);
1332 PlatformThread::CreateNonJoinable(0, reaper); 1387 PlatformThread::CreateNonJoinable(0, reaper);
1333 } 1388 }
1334 1389
1335 #endif // !defined(OS_MACOSX) 1390 #endif // !defined(OS_MACOSX)
1336 1391
1337 } // namespace base 1392 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698