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

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: remove some comments 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 #ifdef USE_ALLOCATED_TYPE
37 #include "base/allocator/allocated_type_tcmalloc.h"
38 #endif
39
36 #if defined(OS_CHROMEOS) 40 #if defined(OS_CHROMEOS)
37 #include <sys/ioctl.h> 41 #include <sys/ioctl.h>
38 #endif 42 #endif
39 43
40 #if defined(OS_FREEBSD) 44 #if defined(OS_FREEBSD)
41 #include <sys/event.h> 45 #include <sys/event.h>
42 #include <sys/ucontext.h> 46 #include <sys/ucontext.h>
43 #endif 47 #endif
44 48
45 #if defined(OS_MACOSX) 49 #if defined(OS_MACOSX)
(...skipping 588 matching lines...) Expand 10 before | Expand all | Expand 10 after
634 if (options.new_process_group) { 638 if (options.new_process_group) {
635 // Instead of inheriting the process group ID of the parent, the child 639 // 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. 640 // starts off a new process group with pgid equal to its process ID.
637 if (setpgid(0, 0) < 0) { 641 if (setpgid(0, 0) < 0) {
638 RAW_LOG(ERROR, "setpgid failed"); 642 RAW_LOG(ERROR, "setpgid failed");
639 _exit(127); 643 _exit(127);
640 } 644 }
641 } 645 }
642 646
643 if (options.maximize_rlimits) { 647 if (options.maximize_rlimits) {
648 #ifdef USE_ALLOCATED_TYPE
649 SuspendAllocatedTypeIntercept();
650 #endif
Dai Mikurube (NOT FULLTIME) 2012/08/02 07:43:55 These are to avoid the DANGER of http://crbug.com/
Nico 2012/08/02 15:35:03 As far as I understand the bug, any code that does
Dai Mikurube (NOT FULLTIME) 2012/08/02 16:14:35 In my understanding, they don't allocate (malloc)
jar (doing other things) 2012/08/02 23:38:30 I don't follow this motivation. ...but... if your
Dai Mikurube (NOT FULLTIME) 2012/08/03 10:01:50 Thank you. That is a good idea. For now, I keep
jar (doing other things) 2012/08/04 01:13:47 Your original comment was "...unreadable. It is ba
Dai Mikurube (NOT FULLTIME) 2012/08/07 10:39:18 I'm still thinking also about removing all STL ope
644 // Some resource limits need to be maximal in this child. 651 // Some resource limits need to be maximal in this child.
645 std::set<int>::const_iterator resource; 652 std::set<int>::const_iterator resource;
646 for (resource = options.maximize_rlimits->begin(); 653 for (resource = options.maximize_rlimits->begin();
647 resource != options.maximize_rlimits->end(); 654 resource != options.maximize_rlimits->end();
648 ++resource) { 655 ++resource) {
649 struct rlimit limit; 656 struct rlimit limit;
650 if (getrlimit(*resource, &limit) < 0) { 657 if (getrlimit(*resource, &limit) < 0) {
651 RAW_LOG(WARNING, "getrlimit failed"); 658 RAW_LOG(WARNING, "getrlimit failed");
652 } else if (limit.rlim_cur < limit.rlim_max) { 659 } else if (limit.rlim_cur < limit.rlim_max) {
653 limit.rlim_cur = limit.rlim_max; 660 limit.rlim_cur = limit.rlim_max;
654 if (setrlimit(*resource, &limit) < 0) { 661 if (setrlimit(*resource, &limit) < 0) {
655 RAW_LOG(WARNING, "setrlimit failed"); 662 RAW_LOG(WARNING, "setrlimit failed");
656 } 663 }
657 } 664 }
658 } 665 }
666 #ifdef USE_ALLOCATED_TYPE
667 ResumeAllocatedTypeIntercept();
668 #endif
659 } 669 }
660 670
661 #if defined(OS_MACOSX) 671 #if defined(OS_MACOSX)
662 RestoreDefaultExceptionHandler(); 672 RestoreDefaultExceptionHandler();
663 #endif // defined(OS_MACOSX) 673 #endif // defined(OS_MACOSX)
664 674
665 ResetChildSignalHandlersToDefaults(); 675 ResetChildSignalHandlersToDefaults();
666 676
667 #if defined(OS_MACOSX) 677 #if defined(OS_MACOSX)
668 if (options.synchronize) { 678 if (options.synchronize) {
(...skipping 22 matching lines...) Expand all
691 ioctl(options.ctrl_terminal_fd, TIOCSCTTY, NULL)) == -1) { 701 ioctl(options.ctrl_terminal_fd, TIOCSCTTY, NULL)) == -1) {
692 RAW_LOG(WARNING, "ioctl(TIOCSCTTY), ctrl terminal not set"); 702 RAW_LOG(WARNING, "ioctl(TIOCSCTTY), ctrl terminal not set");
693 } 703 }
694 } else { 704 } else {
695 RAW_LOG(WARNING, "setsid failed, ctrl terminal not set"); 705 RAW_LOG(WARNING, "setsid failed, ctrl terminal not set");
696 } 706 }
697 } 707 }
698 #endif // defined(OS_CHROMEOS) 708 #endif // defined(OS_CHROMEOS)
699 709
700 if (options.fds_to_remap) { 710 if (options.fds_to_remap) {
711 #ifdef USE_ALLOCATED_TYPE
712 SuspendAllocatedTypeIntercept();
713 #endif
701 for (FileHandleMappingVector::const_iterator 714 for (FileHandleMappingVector::const_iterator
702 it = options.fds_to_remap->begin(); 715 it = options.fds_to_remap->begin();
703 it != options.fds_to_remap->end(); ++it) { 716 it != options.fds_to_remap->end(); ++it) {
704 fd_shuffle1.push_back(InjectionArc(it->first, it->second, false)); 717 fd_shuffle1.push_back(InjectionArc(it->first, it->second, false));
705 fd_shuffle2.push_back(InjectionArc(it->first, it->second, false)); 718 fd_shuffle2.push_back(InjectionArc(it->first, it->second, false));
706 } 719 }
720 #ifdef USE_ALLOCATED_TYPE
721 ResumeAllocatedTypeIntercept();
722 #endif
707 } 723 }
708 724
709 #if defined(OS_MACOSX) 725 #if defined(OS_MACOSX)
710 if (options.synchronize) { 726 if (options.synchronize) {
727 #ifdef USE_ALLOCATED_TYPE
728 SuspendAllocatedTypeIntercept();
729 #endif
711 // Remap the read side of the synchronization pipe back onto itself, 730 // Remap the read side of the synchronization pipe back onto itself,
712 // ensuring that it won't be closed by CloseSuperfluousFds. 731 // ensuring that it won't be closed by CloseSuperfluousFds.
713 int keep_fd = *synchronization_read_fd.get(); 732 int keep_fd = *synchronization_read_fd.get();
714 fd_shuffle1.push_back(InjectionArc(keep_fd, keep_fd, false)); 733 fd_shuffle1.push_back(InjectionArc(keep_fd, keep_fd, false));
715 fd_shuffle2.push_back(InjectionArc(keep_fd, keep_fd, false)); 734 fd_shuffle2.push_back(InjectionArc(keep_fd, keep_fd, false));
735 #ifdef USE_ALLOCATED_TYPE
736 ResumeAllocatedTypeIntercept();
737 #endif
716 } 738 }
717 #endif // defined(OS_MACOSX) 739 #endif // defined(OS_MACOSX)
718 740
719 if (options.environ) 741 if (options.environ)
720 SetEnvironment(new_environ.get()); 742 SetEnvironment(new_environ.get());
721 743
744 #ifdef USE_ALLOCATED_TYPE
745 SuspendAllocatedTypeIntercept();
746 #endif
722 // fd_shuffle1 is mutated by this call because it cannot malloc. 747 // fd_shuffle1 is mutated by this call because it cannot malloc.
723 if (!ShuffleFileDescriptors(&fd_shuffle1)) 748 if (!ShuffleFileDescriptors(&fd_shuffle1)) {
749 #ifdef USE_ALLOCATED_TYPE
750 ResumeAllocatedTypeIntercept();
751 #endif
724 _exit(127); 752 _exit(127);
753 }
725 754
726 CloseSuperfluousFds(fd_shuffle2); 755 CloseSuperfluousFds(fd_shuffle2);
756 #ifdef USE_ALLOCATED_TYPE
757 ResumeAllocatedTypeIntercept();
758 #endif
727 759
728 #if defined(OS_MACOSX) 760 #if defined(OS_MACOSX)
729 if (options.synchronize) { 761 if (options.synchronize) {
730 // Do a blocking read to wait until the parent says it's OK to proceed. 762 // 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. 763 // The byte that's read here is written by LaunchSynchronize.
732 char read_char; 764 char read_char;
733 int read_result = 765 int read_result =
734 HANDLE_EINTR(read(*synchronization_read_fd.get(), &read_char, 1)); 766 HANDLE_EINTR(read(*synchronization_read_fd.get(), &read_char, 1));
735 if (read_result != 1) { 767 if (read_result != 1) {
736 RAW_LOG(ERROR, "LaunchProcess: synchronization read: error"); 768 RAW_LOG(ERROR, "LaunchProcess: synchronization read: error");
737 _exit(127); 769 _exit(127);
738 } 770 }
739 771
740 // The pipe is no longer useful. Don't let it live on in the new process 772 // The pipe is no longer useful. Don't let it live on in the new process
741 // after exec. 773 // after exec.
742 synchronization_read_fd.reset(); // closes synchronization_pipe_fds[0] 774 synchronization_read_fd.reset(); // closes synchronization_pipe_fds[0]
743 } 775 }
744 #endif // defined(OS_MACOSX) 776 #endif // defined(OS_MACOSX)
745 777
778 #ifdef USE_ALLOCATED_TYPE
779 SuspendAllocatedTypeIntercept();
780 #endif
746 for (size_t i = 0; i < argv.size(); i++) 781 for (size_t i = 0; i < argv.size(); i++)
747 argv_cstr[i] = const_cast<char*>(argv[i].c_str()); 782 argv_cstr[i] = const_cast<char*>(argv[i].c_str());
748 argv_cstr[argv.size()] = NULL; 783 argv_cstr[argv.size()] = NULL;
784 #ifdef USE_ALLOCATED_TYPE
785 ResumeAllocatedTypeIntercept();
Alexander Potapenko 2012/08/02 14:57:12 There's no point in resuming the interception if t
Dai Mikurube (NOT FULLTIME) 2012/08/03 10:01:50 Ah, right. For now, I kept it as is, but I added
jar (doing other things) 2012/08/04 01:13:47 It strikes me that when you fork, you don't want t
Dai Mikurube (NOT FULLTIME) 2012/08/07 10:39:18 Ahhh, maybe, you are right. guessing we can suspe
786 #endif
749 execvp(argv_cstr[0], argv_cstr.get()); 787 execvp(argv_cstr[0], argv_cstr.get());
750 788
751 RAW_LOG(ERROR, "LaunchProcess: failed to execvp:"); 789 RAW_LOG(ERROR, "LaunchProcess: failed to execvp:");
752 RAW_LOG(ERROR, argv_cstr[0]); 790 RAW_LOG(ERROR, argv_cstr[0]);
753 _exit(127); 791 _exit(127);
754 } else { 792 } else {
755 // Parent process 793 // Parent process
756 if (options.wait) { 794 if (options.wait) {
757 // While this isn't strictly disk IO, waiting for another process to 795 // While this isn't strictly disk IO, waiting for another process to
758 // finish is the sort of thing ThreadRestrictions is trying to prevent. 796 // finish is the sort of thing ThreadRestrictions is trying to prevent.
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after
1101 1139
1102 // Obscure fork() rule: in the child, if you don't end up doing exec*(), 1140 // 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 1141 // you call _exit() instead of exit(). This is because _exit() does not
1104 // call any previously-registered (in the parent) exit handlers, which 1142 // call any previously-registered (in the parent) exit handlers, which
1105 // might do things like block waiting for threads that don't even exist 1143 // might do things like block waiting for threads that don't even exist
1106 // in the child. 1144 // in the child.
1107 int dev_null = open("/dev/null", O_WRONLY); 1145 int dev_null = open("/dev/null", O_WRONLY);
1108 if (dev_null < 0) 1146 if (dev_null < 0)
1109 _exit(127); 1147 _exit(127);
1110 1148
1149 #ifdef USE_ALLOCATED_TYPE
1150 SuspendAllocatedTypeIntercept();
1151 #endif
1111 fd_shuffle1.push_back(InjectionArc(pipe_fd[1], STDOUT_FILENO, true)); 1152 fd_shuffle1.push_back(InjectionArc(pipe_fd[1], STDOUT_FILENO, true));
1112 fd_shuffle1.push_back(InjectionArc(dev_null, STDERR_FILENO, true)); 1153 fd_shuffle1.push_back(InjectionArc(dev_null, STDERR_FILENO, true));
1113 fd_shuffle1.push_back(InjectionArc(dev_null, STDIN_FILENO, true)); 1154 fd_shuffle1.push_back(InjectionArc(dev_null, STDIN_FILENO, true));
1114 // Adding another element here? Remeber to increase the argument to 1155 // Adding another element here? Remeber to increase the argument to
1115 // reserve(), above. 1156 // reserve(), above.
1116 1157
1117 std::copy(fd_shuffle1.begin(), fd_shuffle1.end(), 1158 std::copy(fd_shuffle1.begin(), fd_shuffle1.end(),
1118 std::back_inserter(fd_shuffle2)); 1159 std::back_inserter(fd_shuffle2));
1119 1160
1120 if (!ShuffleFileDescriptors(&fd_shuffle1)) 1161 if (!ShuffleFileDescriptors(&fd_shuffle1)) {
1162 #ifdef USE_ALLOCATED_TYPE
1163 ResumeAllocatedTypeIntercept();
1164 #endif
1121 _exit(127); 1165 _exit(127);
1166 }
1122 1167
1123 CloseSuperfluousFds(fd_shuffle2); 1168 CloseSuperfluousFds(fd_shuffle2);
1124 1169
1125 for (size_t i = 0; i < argv.size(); i++) 1170 for (size_t i = 0; i < argv.size(); i++)
1126 argv_cstr[i] = const_cast<char*>(argv[i].c_str()); 1171 argv_cstr[i] = const_cast<char*>(argv[i].c_str());
1127 argv_cstr[argv.size()] = NULL; 1172 argv_cstr[argv.size()] = NULL;
1173 #ifdef USE_ALLOCATED_TYPE
1174 ResumeAllocatedTypeIntercept();
1175 #endif
1128 if (do_search_path) 1176 if (do_search_path)
1129 execvp(argv_cstr[0], argv_cstr.get()); 1177 execvp(argv_cstr[0], argv_cstr.get());
1130 else 1178 else
1131 execve(argv_cstr[0], argv_cstr.get(), envp); 1179 execve(argv_cstr[0], argv_cstr.get(), envp);
1132 _exit(127); 1180 _exit(127);
1133 } 1181 }
1134 default: // parent 1182 default: // parent
1135 { 1183 {
1136 // Close our writing end of pipe now. Otherwise later read would not 1184 // 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 1185 // 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)) 1376 if (IsChildDead(process))
1329 return; 1377 return;
1330 1378
1331 BackgroundReaper* reaper = new BackgroundReaper(process, 0); 1379 BackgroundReaper* reaper = new BackgroundReaper(process, 0);
1332 PlatformThread::CreateNonJoinable(0, reaper); 1380 PlatformThread::CreateNonJoinable(0, reaper);
1333 } 1381 }
1334 1382
1335 #endif // !defined(OS_MACOSX) 1383 #endif // !defined(OS_MACOSX)
1336 1384
1337 } // namespace base 1385 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698