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

Side by Side Diff: third_party/tcmalloc/chromium/src/base/sysinfo.cc

Issue 1076002: Revert 41938 - Merged third_party/tcmalloc/vendor/src(googleperftools r87) in... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 10 years, 9 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) 2006, Google Inc. 1 // Copyright (c) 2006, Google Inc.
2 // All rights reserved. 2 // All rights reserved.
3 // 3 //
4 // Redistribution and use in source and binary forms, with or without 4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are 5 // modification, are permitted provided that the following conditions are
6 // met: 6 // met:
7 // 7 //
8 // * Redistributions of source code must retain the above copyright 8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer. 9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above 10 // * Redistributions in binary form must reproduce the above
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 # define saferead(fd, buffer, size) read(fd, buffer, size) 93 # define saferead(fd, buffer, size) read(fd, buffer, size)
94 # define safeclose(fd) close(fd) 94 # define safeclose(fd) close(fd)
95 #endif 95 #endif
96 96
97 // ---------------------------------------------------------------------- 97 // ----------------------------------------------------------------------
98 // GetenvBeforeMain() 98 // GetenvBeforeMain()
99 // GetUniquePathFromEnv() 99 // GetUniquePathFromEnv()
100 // Some non-trivial getenv-related functions. 100 // Some non-trivial getenv-related functions.
101 // ---------------------------------------------------------------------- 101 // ----------------------------------------------------------------------
102 102
103 // It's not safe to call getenv() in the malloc hooks, because they
104 // might be called extremely early, before libc is done setting up
105 // correctly. In particular, the thread library may not be done
106 // setting up errno. So instead, we use the built-in __environ array
107 // if it exists, and otherwise read /proc/self/environ directly, using
108 // system calls to read the file, and thus avoid setting errno.
109 // /proc/self/environ has a limit of how much data it exports (around
110 // 8K), so it's not an ideal solution.
111 const char* GetenvBeforeMain(const char* name) { 103 const char* GetenvBeforeMain(const char* name) {
112 #if defined(HAVE___ENVIRON) // if we have it, it's declared in unistd.h
113 const int namelen = strlen(name);
114 for (char** p = __environ; *p; p++) {
115 if (!memcmp(*p, name, namelen) && (*p)[namelen] == '=') // it's a match
116 return *p + namelen+1; // point after =
117 }
118 return NULL;
119 #elif defined(PLATFORM_WINDOWS)
120 // TODO(mbelshe) - repeated calls to this function will overwrite the
121 // contents of the static buffer.
122 static char envbuf[1024]; // enough to hold any envvar we care about
123 if (!GetEnvironmentVariableA(name, envbuf, sizeof(envbuf)-1))
124 return NULL;
125 return envbuf;
126 #else
127 // static is ok because this function should only be called before 104 // static is ok because this function should only be called before
128 // main(), when we're single-threaded. 105 // main(), when we're single-threaded.
129 static char envbuf[16<<10]; 106 static char envbuf[16<<10];
107 #ifndef PLATFORM_WINDOWS
130 if (*envbuf == '\0') { // haven't read the environ yet 108 if (*envbuf == '\0') { // haven't read the environ yet
131 int fd = safeopen("/proc/self/environ", O_RDONLY); 109 int fd = safeopen("/proc/self/environ", O_RDONLY);
132 // The -2 below guarantees the last two bytes of the buffer will be \0\0 110 // The -2 below guarantees the last two bytes of the buffer will be \0\0
133 if (fd == -1 || // unable to open the file, fall back onto libc 111 if (fd == -1 || // unable to open the file, fall back onto libc
134 saferead(fd, envbuf, sizeof(envbuf) - 2) < 0) { // error reading file 112 saferead(fd, envbuf, sizeof(envbuf) - 2) < 0) { // error reading file
135 RAW_VLOG(1, "Unable to open /proc/self/environ, falling back " 113 RAW_VLOG(1, "Unable to open /proc/self/environ, falling back "
136 "on getenv(\"%s\"), which may not work", name); 114 "on getenv(\"%s\"), which may not work", name);
137 if (fd != -1) safeclose(fd); 115 if (fd != -1) safeclose(fd);
138 return getenv(name); 116 return getenv(name);
139 } 117 }
140 safeclose(fd); 118 safeclose(fd);
141 } 119 }
142 const int namelen = strlen(name); 120 const int namelen = strlen(name);
143 const char* p = envbuf; 121 const char* p = envbuf;
144 while (*p != '\0') { // will happen at the \0\0 that terminates the buffer 122 while (*p != '\0') { // will happen at the \0\0 that terminates the buffer
145 // proc file has the format NAME=value\0NAME=value\0NAME=value\0... 123 // proc file has the format NAME=value\0NAME=value\0NAME=value\0...
146 const char* endp = (char*)memchr(p, '\0', sizeof(envbuf) - (p - envbuf)); 124 const char* endp = (char*)memchr(p, '\0', sizeof(envbuf) - (p - envbuf));
147 if (endp == NULL) // this entry isn't NUL terminated 125 if (endp == NULL) // this entry isn't NUL terminated
148 return NULL; 126 return NULL;
149 else if (!memcmp(p, name, namelen) && p[namelen] == '=') // it's a match 127 else if (!memcmp(p, name, namelen) && p[namelen] == '=') // it's a match
150 return p + namelen+1; // point after = 128 return p + namelen+1; // point after =
151 p = endp + 1; 129 p = endp + 1;
152 } 130 }
153 return NULL; // env var never found 131 return NULL; // env var never found
132 #else
133 // TODO(mbelshe) - repeated calls to this function will overwrite the
134 // contents of the static buffer.
135 if (!GetEnvironmentVariableA(name, envbuf, sizeof(envbuf)-1))
136 return NULL;
137 return envbuf;
154 #endif 138 #endif
155 } 139 }
156 140
157 // This takes as an argument an environment-variable name (like 141 // This takes as an argument an environment-variable name (like
158 // CPUPROFILE) whose value is supposed to be a file-path, and sets 142 // CPUPROFILE) whose value is supposed to be a file-path, and sets
159 // path to that path, and returns true. If the env var doesn't exist, 143 // path to that path, and returns true. If the env var doesn't exist,
160 // or is the empty string, leave path unchanged and returns false. 144 // or is the empty string, leave path unchanged and returns false.
161 // The reason this is non-trivial is that this function handles munged 145 // The reason this is non-trivial is that this function handles munged
162 // pathnames. Here's why: 146 // pathnames. Here's why:
163 // 147 //
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after
450 434
451 #if defined __linux__ || defined __FreeBSD__ || defined __sun__ || defined __CYG WIN__ || defined __CYGWIN32__ 435 #if defined __linux__ || defined __FreeBSD__ || defined __sun__ || defined __CYG WIN__ || defined __CYGWIN32__
452 static void ConstructFilename(const char* spec, pid_t pid, 436 static void ConstructFilename(const char* spec, pid_t pid,
453 char* buf, int buf_size) { 437 char* buf, int buf_size) {
454 CHECK_LT(snprintf(buf, buf_size, 438 CHECK_LT(snprintf(buf, buf_size,
455 spec, 439 spec,
456 pid ? pid : getpid()), buf_size); 440 pid ? pid : getpid()), buf_size);
457 } 441 }
458 #endif 442 #endif
459 443
460 // A templatized helper function instantiated for Mach (OS X) only.
461 // It can handle finding info for both 32 bits and 64 bits.
462 // Returns true if it successfully handled the hdr, false else.
463 #ifdef __MACH__ // Mac OS X, almost certainly
464 template<uint32_t kMagic, uint32_t kLCSegment,
465 typename MachHeader, typename SegmentCommand>
466 static bool NextExtMachHelper(const mach_header* hdr,
467 int current_image, int current_load_cmd,
468 uint64 *start, uint64 *end, char **flags,
469 uint64 *offset, int64 *inode, char **filename,
470 uint64 *file_mapping, uint64 *file_pages,
471 uint64 *anon_mapping, uint64 *anon_pages,
472 dev_t *dev) {
473 static char kDefaultPerms[5] = "r-xp";
474 if (hdr->magic != kMagic)
475 return false;
476 const char* lc = (const char *)hdr + sizeof(MachHeader);
477 // TODO(csilvers): make this not-quadradic (increment and hold state)
478 for (int j = 0; j < current_load_cmd; j++) // advance to *our* load_cmd
479 lc += ((const load_command *)lc)->cmdsize;
480 if (((const load_command *)lc)->cmd == kLCSegment) {
481 const intptr_t dlloff = _dyld_get_image_vmaddr_slide(current_image);
482 const SegmentCommand* sc = (const SegmentCommand *)lc;
483 if (start) *start = sc->vmaddr + dlloff;
484 if (end) *end = sc->vmaddr + sc->vmsize + dlloff;
485 if (flags) *flags = kDefaultPerms; // can we do better?
486 if (offset) *offset = sc->fileoff;
487 if (inode) *inode = 0;
488 if (filename)
489 *filename = const_cast<char*>(_dyld_get_image_name(current_image));
490 if (file_mapping) *file_mapping = 0;
491 if (file_pages) *file_pages = 0; // could we use sc->filesize?
492 if (anon_mapping) *anon_mapping = 0;
493 if (anon_pages) *anon_pages = 0;
494 if (dev) *dev = 0;
495 return true;
496 }
497
498 return false;
499 }
500 #endif
501
502 ProcMapsIterator::ProcMapsIterator(pid_t pid) { 444 ProcMapsIterator::ProcMapsIterator(pid_t pid) {
503 Init(pid, NULL, false); 445 Init(pid, NULL, false);
504 } 446 }
505 447
506 ProcMapsIterator::ProcMapsIterator(pid_t pid, Buffer *buffer) { 448 ProcMapsIterator::ProcMapsIterator(pid_t pid, Buffer *buffer) {
507 Init(pid, buffer, false); 449 Init(pid, buffer, false);
508 } 450 }
509 451
510 ProcMapsIterator::ProcMapsIterator(pid_t pid, Buffer *buffer, 452 ProcMapsIterator::ProcMapsIterator(pid_t pid, Buffer *buffer,
511 bool use_maps_backing) { 453 bool use_maps_backing) {
512 Init(pid, buffer, use_maps_backing); 454 Init(pid, buffer, use_maps_backing);
513 } 455 }
514 456
515 void ProcMapsIterator::Init(pid_t pid, Buffer *buffer, 457 void ProcMapsIterator::Init(pid_t pid, Buffer *buffer,
516 bool use_maps_backing) { 458 bool use_maps_backing) {
517 pid_ = pid;
518 using_maps_backing_ = use_maps_backing; 459 using_maps_backing_ = use_maps_backing;
519 dynamic_buffer_ = NULL; 460 dynamic_buffer_ = NULL;
520 if (!buffer) { 461 if (!buffer) {
521 // If the user didn't pass in any buffer storage, allocate it 462 // If the user didn't pass in any buffer storage, allocate it
522 // now. This is the normal case; the signal handler passes in a 463 // now. This is the normal case; the signal handler passes in a
523 // static buffer. 464 // static buffer.
524 buffer = dynamic_buffer_ = new Buffer; 465 buffer = dynamic_buffer_ = new Buffer;
525 } else { 466 } else {
526 dynamic_buffer_ = NULL; 467 dynamic_buffer_ = NULL;
527 } 468 }
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
743 684
744 return true; 685 return true;
745 } while (etext_ > ibuf_); 686 } while (etext_ > ibuf_);
746 #elif defined(__sun__) 687 #elif defined(__sun__)
747 // This is based on MA_READ == 4, MA_WRITE == 2, MA_EXEC == 1 688 // This is based on MA_READ == 4, MA_WRITE == 2, MA_EXEC == 1
748 static char kPerms[8][4] = { "---", "--x", "-w-", "-wx", 689 static char kPerms[8][4] = { "---", "--x", "-w-", "-wx",
749 "r--", "r-x", "rw-", "rwx" }; 690 "r--", "r-x", "rw-", "rwx" };
750 COMPILE_ASSERT(MA_READ == 4, solaris_ma_read_must_equal_4); 691 COMPILE_ASSERT(MA_READ == 4, solaris_ma_read_must_equal_4);
751 COMPILE_ASSERT(MA_WRITE == 2, solaris_ma_write_must_equal_2); 692 COMPILE_ASSERT(MA_WRITE == 2, solaris_ma_write_must_equal_2);
752 COMPILE_ASSERT(MA_EXEC == 1, solaris_ma_exec_must_equal_1); 693 COMPILE_ASSERT(MA_EXEC == 1, solaris_ma_exec_must_equal_1);
753 Buffer object_path;
754 int nread = 0; // fill up buffer with text 694 int nread = 0; // fill up buffer with text
755 NO_INTR(nread = read(fd_, ibuf_, sizeof(prmap_t))); 695 NO_INTR(nread = read(fd_, ibuf_, sizeof(prmap_t)));
756 if (nread == sizeof(prmap_t)) { 696 if (nread == sizeof(prmap_t)) {
757 long inode_from_mapname = 0; 697 long inode_from_mapname = 0;
758 prmap_t* mapinfo = reinterpret_cast<prmap_t*>(ibuf_); 698 prmap_t* mapinfo = reinterpret_cast<prmap_t*>(ibuf_);
759 // Best-effort attempt to get the inode from the filename. I think the 699 // Best-effort attempt to get the inode from the filename. I think the
760 // two middle ints are major and minor device numbers, but I'm not sure. 700 // two middle ints are major and minor device numbers, but I'm not sure.
761 sscanf(mapinfo->pr_mapname, "ufs.%*d.%*d.%ld", &inode_from_mapname); 701 sscanf(mapinfo->pr_mapname, "ufs.%*d.%*d.%ld", &inode_from_mapname);
762 702
763 if (pid_ == 0) {
764 CHECK_LT(snprintf(object_path.buf_, Buffer::kBufSize,
765 "/proc/self/path/%s", mapinfo->pr_mapname),
766 Buffer::kBufSize);
767 } else {
768 CHECK_LT(snprintf(object_path.buf_, Buffer::kBufSize,
769 "/proc/%d/path/%s", pid_, mapinfo->pr_mapname),
770 Buffer::kBufSize);
771 }
772 ssize_t len = readlink(object_path.buf_, current_filename_, PATH_MAX);
773 CHECK_LT(len, PATH_MAX);
774 if (len < 0)
775 len = 0;
776 current_filename_[len] = '\0';
777
778 if (start) *start = mapinfo->pr_vaddr; 703 if (start) *start = mapinfo->pr_vaddr;
779 if (end) *end = mapinfo->pr_vaddr + mapinfo->pr_size; 704 if (end) *end = mapinfo->pr_vaddr + mapinfo->pr_size;
780 if (flags) *flags = kPerms[mapinfo->pr_mflags & 7]; 705 if (flags) *flags = kPerms[mapinfo->pr_mflags & 7];
781 if (offset) *offset = mapinfo->pr_offset; 706 if (offset) *offset = mapinfo->pr_offset;
782 if (inode) *inode = inode_from_mapname; 707 if (inode) *inode = inode_from_mapname;
783 if (filename) *filename = current_filename_; 708 // TODO(csilvers): How to map from /proc/map/object to filename?
709 if (filename) *filename = mapinfo->pr_mapname; // format is ufs.?.?.inode
784 if (file_mapping) *file_mapping = 0; 710 if (file_mapping) *file_mapping = 0;
785 if (file_pages) *file_pages = 0; 711 if (file_pages) *file_pages = 0;
786 if (anon_mapping) *anon_mapping = 0; 712 if (anon_mapping) *anon_mapping = 0;
787 if (anon_pages) *anon_pages = 0; 713 if (anon_pages) *anon_pages = 0;
788 if (dev) *dev = 0; 714 if (dev) *dev = 0;
789 return true; 715 return true;
790 } 716 }
791 #elif defined(__MACH__) 717 #elif defined(__MACH__)
718 static char kDefaultPerms[5] = "r-xp";
792 // We return a separate entry for each segment in the DLL. (TODO(csilvers): 719 // We return a separate entry for each segment in the DLL. (TODO(csilvers):
793 // can we do better?) A DLL ("image") has load-commands, some of which 720 // can we do better?) A DLL ("image") has load-commands, some of which
794 // talk about segment boundaries. 721 // talk about segment boundaries.
795 // cf image_for_address from http://svn.digium.com/view/asterisk/team/oej/mini voicemail/dlfcn.c?revision=53912 722 // cf image_for_address from http://svn.digium.com/view/asterisk/team/oej/mini voicemail/dlfcn.c?revision=53912
796 for (; current_image_ >= 0; current_image_--) { 723 for (; current_image_ >= 0; current_image_--) {
797 const mach_header* hdr = _dyld_get_image_header(current_image_); 724 const mach_header* hdr = _dyld_get_image_header(current_image_);
798 if (!hdr) continue; 725 if (!hdr) continue;
799 if (current_load_cmd_ < 0) // set up for this image 726 if (current_load_cmd_ < 0) // set up for this image
800 current_load_cmd_ = hdr->ncmds; // again, go from the top down 727 current_load_cmd_ = hdr->ncmds; // again, go from the top down
801 728
802 // We start with the next load command (we've already looked at this one). 729 // We start with the next load command (we've already looked at this one).
803 for (current_load_cmd_--; current_load_cmd_ >= 0; current_load_cmd_--) { 730 for (current_load_cmd_--; current_load_cmd_ >= 0; current_load_cmd_--) {
804 #ifdef MH_MAGIC_64 731 const char* lc = ((const char *)hdr + sizeof(struct mach_header));
805 if (NextExtMachHelper<MH_MAGIC_64, LC_SEGMENT_64, 732 // TODO(csilvers): make this not-quadradic (increment and hold state)
806 struct mach_header_64, struct segment_command_64>( 733 for (int j = 0; j < current_load_cmd_; j++) // advance to *our* load_cmd
807 hdr, current_image_, current_load_cmd_, 734 lc += ((const load_command *)lc)->cmdsize;
808 start, end, flags, offset, inode, filename, 735 if (((const load_command *)lc)->cmd == LC_SEGMENT) {
809 file_mapping, file_pages, anon_mapping, 736 const intptr_t dlloff = _dyld_get_image_vmaddr_slide(current_image_);
810 anon_pages, dev)) { 737 const segment_command* sc = (const segment_command *)lc;
811 return true; 738 if (start) *start = sc->vmaddr + dlloff;
812 } 739 if (end) *end = sc->vmaddr + sc->vmsize + dlloff;
813 #endif 740 if (flags) *flags = kDefaultPerms; // can we do better?
814 if (NextExtMachHelper<MH_MAGIC, LC_SEGMENT, 741 if (offset) *offset = sc->fileoff;
815 struct mach_header, struct segment_command>( 742 if (inode) *inode = 0;
816 hdr, current_image_, current_load_cmd_, 743 if (filename)
817 start, end, flags, offset, inode, filename, 744 *filename = const_cast<char*>(_dyld_get_image_name(current_image_));
818 file_mapping, file_pages, anon_mapping, 745 if (file_mapping) *file_mapping = 0;
819 anon_pages, dev)) { 746 if (file_pages) *file_pages = 0; // could we use sc->filesize?
747 if (anon_mapping) *anon_mapping = 0;
748 if (anon_pages) *anon_pages = 0;
749 if (dev) *dev = 0;
820 return true; 750 return true;
821 } 751 }
822 } 752 }
823 // If we get here, no more load_cmd's in this image talk about 753 // If we get here, no more load_cmd's in this image talk about
824 // segments. Go on to the next image. 754 // segments. Go on to the next image.
825 } 755 }
826 #elif defined(PLATFORM_WINDOWS) 756 #elif defined(PLATFORM_WINDOWS)
827 static char kDefaultPerms[5] = "r-xp"; 757 static char kDefaultPerms[5] = "r-xp";
828 BOOL ok; 758 BOOL ok;
829 if (module_.dwSize == 0) { // only possible before first call 759 if (module_.dwSize == 0) { // only possible before first call
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
908 ProcMapsIterator::Buffer linebuf; 838 ProcMapsIterator::Buffer linebuf;
909 while (it.Next(&start, &end, &flags, &offset, &inode, &filename)) { 839 while (it.Next(&start, &end, &flags, &offset, &inode, &filename)) {
910 int written = it.FormatLine(linebuf.buf_, sizeof(linebuf.buf_), 840 int written = it.FormatLine(linebuf.buf_, sizeof(linebuf.buf_),
911 start, end, flags, offset, inode, filename, 841 start, end, flags, offset, inode, filename,
912 0); 842 0);
913 RawWrite(fd, linebuf.buf_, written); 843 RawWrite(fd, linebuf.buf_, written);
914 } 844 }
915 } 845 }
916 846
917 } // namespace tcmalloc 847 } // namespace tcmalloc
OLDNEW
« no previous file with comments | « third_party/tcmalloc/chromium/src/base/sysinfo.h ('k') | third_party/tcmalloc/chromium/src/config.h.in » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698