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

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

Issue 576001: Merged third_party/tcmalloc/vendor/src(google-perftools r87) into... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Removed the unnecessary printf and ASSERT(0) 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.
103 const char* GetenvBeforeMain(const char* name) { 111 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
104 // static is ok because this function should only be called before 127 // static is ok because this function should only be called before
105 // main(), when we're single-threaded. 128 // main(), when we're single-threaded.
106 static char envbuf[16<<10]; 129 static char envbuf[16<<10];
107 #ifndef PLATFORM_WINDOWS
108 if (*envbuf == '\0') { // haven't read the environ yet 130 if (*envbuf == '\0') { // haven't read the environ yet
109 int fd = safeopen("/proc/self/environ", O_RDONLY); 131 int fd = safeopen("/proc/self/environ", O_RDONLY);
110 // The -2 below guarantees the last two bytes of the buffer will be \0\0 132 // The -2 below guarantees the last two bytes of the buffer will be \0\0
111 if (fd == -1 || // unable to open the file, fall back onto libc 133 if (fd == -1 || // unable to open the file, fall back onto libc
112 saferead(fd, envbuf, sizeof(envbuf) - 2) < 0) { // error reading file 134 saferead(fd, envbuf, sizeof(envbuf) - 2) < 0) { // error reading file
113 RAW_VLOG(1, "Unable to open /proc/self/environ, falling back " 135 RAW_VLOG(1, "Unable to open /proc/self/environ, falling back "
114 "on getenv(\"%s\"), which may not work", name); 136 "on getenv(\"%s\"), which may not work", name);
115 if (fd != -1) safeclose(fd); 137 if (fd != -1) safeclose(fd);
116 return getenv(name); 138 return getenv(name);
117 } 139 }
118 safeclose(fd); 140 safeclose(fd);
119 } 141 }
120 const int namelen = strlen(name); 142 const int namelen = strlen(name);
121 const char* p = envbuf; 143 const char* p = envbuf;
122 while (*p != '\0') { // will happen at the \0\0 that terminates the buffer 144 while (*p != '\0') { // will happen at the \0\0 that terminates the buffer
123 // proc file has the format NAME=value\0NAME=value\0NAME=value\0... 145 // proc file has the format NAME=value\0NAME=value\0NAME=value\0...
124 const char* endp = (char*)memchr(p, '\0', sizeof(envbuf) - (p - envbuf)); 146 const char* endp = (char*)memchr(p, '\0', sizeof(envbuf) - (p - envbuf));
125 if (endp == NULL) // this entry isn't NUL terminated 147 if (endp == NULL) // this entry isn't NUL terminated
126 return NULL; 148 return NULL;
127 else if (!memcmp(p, name, namelen) && p[namelen] == '=') // it's a match 149 else if (!memcmp(p, name, namelen) && p[namelen] == '=') // it's a match
128 return p + namelen+1; // point after = 150 return p + namelen+1; // point after =
129 p = endp + 1; 151 p = endp + 1;
130 } 152 }
131 return NULL; // env var never found 153 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;
138 #endif 154 #endif
139 } 155 }
140 156
141 // This takes as an argument an environment-variable name (like 157 // This takes as an argument an environment-variable name (like
142 // CPUPROFILE) whose value is supposed to be a file-path, and sets 158 // CPUPROFILE) whose value is supposed to be a file-path, and sets
143 // path to that path, and returns true. If the env var doesn't exist, 159 // path to that path, and returns true. If the env var doesn't exist,
144 // or is the empty string, leave path unchanged and returns false. 160 // or is the empty string, leave path unchanged and returns false.
145 // The reason this is non-trivial is that this function handles munged 161 // The reason this is non-trivial is that this function handles munged
146 // pathnames. Here's why: 162 // pathnames. Here's why:
147 // 163 //
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after
434 450
435 #if defined __linux__ || defined __FreeBSD__ || defined __sun__ || defined __CYG WIN__ || defined __CYGWIN32__ 451 #if defined __linux__ || defined __FreeBSD__ || defined __sun__ || defined __CYG WIN__ || defined __CYGWIN32__
436 static void ConstructFilename(const char* spec, pid_t pid, 452 static void ConstructFilename(const char* spec, pid_t pid,
437 char* buf, int buf_size) { 453 char* buf, int buf_size) {
438 CHECK_LT(snprintf(buf, buf_size, 454 CHECK_LT(snprintf(buf, buf_size,
439 spec, 455 spec,
440 pid ? pid : getpid()), buf_size); 456 pid ? pid : getpid()), buf_size);
441 } 457 }
442 #endif 458 #endif
443 459
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
444 ProcMapsIterator::ProcMapsIterator(pid_t pid) { 502 ProcMapsIterator::ProcMapsIterator(pid_t pid) {
445 Init(pid, NULL, false); 503 Init(pid, NULL, false);
446 } 504 }
447 505
448 ProcMapsIterator::ProcMapsIterator(pid_t pid, Buffer *buffer) { 506 ProcMapsIterator::ProcMapsIterator(pid_t pid, Buffer *buffer) {
449 Init(pid, buffer, false); 507 Init(pid, buffer, false);
450 } 508 }
451 509
452 ProcMapsIterator::ProcMapsIterator(pid_t pid, Buffer *buffer, 510 ProcMapsIterator::ProcMapsIterator(pid_t pid, Buffer *buffer,
453 bool use_maps_backing) { 511 bool use_maps_backing) {
454 Init(pid, buffer, use_maps_backing); 512 Init(pid, buffer, use_maps_backing);
455 } 513 }
456 514
457 void ProcMapsIterator::Init(pid_t pid, Buffer *buffer, 515 void ProcMapsIterator::Init(pid_t pid, Buffer *buffer,
458 bool use_maps_backing) { 516 bool use_maps_backing) {
517 pid_ = pid;
459 using_maps_backing_ = use_maps_backing; 518 using_maps_backing_ = use_maps_backing;
460 dynamic_buffer_ = NULL; 519 dynamic_buffer_ = NULL;
461 if (!buffer) { 520 if (!buffer) {
462 // If the user didn't pass in any buffer storage, allocate it 521 // If the user didn't pass in any buffer storage, allocate it
463 // now. This is the normal case; the signal handler passes in a 522 // now. This is the normal case; the signal handler passes in a
464 // static buffer. 523 // static buffer.
465 buffer = dynamic_buffer_ = new Buffer; 524 buffer = dynamic_buffer_ = new Buffer;
466 } else { 525 } else {
467 dynamic_buffer_ = NULL; 526 dynamic_buffer_ = NULL;
468 } 527 }
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
684 743
685 return true; 744 return true;
686 } while (etext_ > ibuf_); 745 } while (etext_ > ibuf_);
687 #elif defined(__sun__) 746 #elif defined(__sun__)
688 // This is based on MA_READ == 4, MA_WRITE == 2, MA_EXEC == 1 747 // This is based on MA_READ == 4, MA_WRITE == 2, MA_EXEC == 1
689 static char kPerms[8][4] = { "---", "--x", "-w-", "-wx", 748 static char kPerms[8][4] = { "---", "--x", "-w-", "-wx",
690 "r--", "r-x", "rw-", "rwx" }; 749 "r--", "r-x", "rw-", "rwx" };
691 COMPILE_ASSERT(MA_READ == 4, solaris_ma_read_must_equal_4); 750 COMPILE_ASSERT(MA_READ == 4, solaris_ma_read_must_equal_4);
692 COMPILE_ASSERT(MA_WRITE == 2, solaris_ma_write_must_equal_2); 751 COMPILE_ASSERT(MA_WRITE == 2, solaris_ma_write_must_equal_2);
693 COMPILE_ASSERT(MA_EXEC == 1, solaris_ma_exec_must_equal_1); 752 COMPILE_ASSERT(MA_EXEC == 1, solaris_ma_exec_must_equal_1);
753 Buffer object_path;
694 int nread = 0; // fill up buffer with text 754 int nread = 0; // fill up buffer with text
695 NO_INTR(nread = read(fd_, ibuf_, sizeof(prmap_t))); 755 NO_INTR(nread = read(fd_, ibuf_, sizeof(prmap_t)));
696 if (nread == sizeof(prmap_t)) { 756 if (nread == sizeof(prmap_t)) {
697 long inode_from_mapname = 0; 757 long inode_from_mapname = 0;
698 prmap_t* mapinfo = reinterpret_cast<prmap_t*>(ibuf_); 758 prmap_t* mapinfo = reinterpret_cast<prmap_t*>(ibuf_);
699 // Best-effort attempt to get the inode from the filename. I think the 759 // Best-effort attempt to get the inode from the filename. I think the
700 // two middle ints are major and minor device numbers, but I'm not sure. 760 // two middle ints are major and minor device numbers, but I'm not sure.
701 sscanf(mapinfo->pr_mapname, "ufs.%*d.%*d.%ld", &inode_from_mapname); 761 sscanf(mapinfo->pr_mapname, "ufs.%*d.%*d.%ld", &inode_from_mapname);
702 762
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
703 if (start) *start = mapinfo->pr_vaddr; 778 if (start) *start = mapinfo->pr_vaddr;
704 if (end) *end = mapinfo->pr_vaddr + mapinfo->pr_size; 779 if (end) *end = mapinfo->pr_vaddr + mapinfo->pr_size;
705 if (flags) *flags = kPerms[mapinfo->pr_mflags & 7]; 780 if (flags) *flags = kPerms[mapinfo->pr_mflags & 7];
706 if (offset) *offset = mapinfo->pr_offset; 781 if (offset) *offset = mapinfo->pr_offset;
707 if (inode) *inode = inode_from_mapname; 782 if (inode) *inode = inode_from_mapname;
708 // TODO(csilvers): How to map from /proc/map/object to filename? 783 if (filename) *filename = current_filename_;
709 if (filename) *filename = mapinfo->pr_mapname; // format is ufs.?.?.inode
710 if (file_mapping) *file_mapping = 0; 784 if (file_mapping) *file_mapping = 0;
711 if (file_pages) *file_pages = 0; 785 if (file_pages) *file_pages = 0;
712 if (anon_mapping) *anon_mapping = 0; 786 if (anon_mapping) *anon_mapping = 0;
713 if (anon_pages) *anon_pages = 0; 787 if (anon_pages) *anon_pages = 0;
714 if (dev) *dev = 0; 788 if (dev) *dev = 0;
715 return true; 789 return true;
716 } 790 }
717 #elif defined(__MACH__) 791 #elif defined(__MACH__)
718 static char kDefaultPerms[5] = "r-xp";
719 // We return a separate entry for each segment in the DLL. (TODO(csilvers): 792 // We return a separate entry for each segment in the DLL. (TODO(csilvers):
720 // can we do better?) A DLL ("image") has load-commands, some of which 793 // can we do better?) A DLL ("image") has load-commands, some of which
721 // talk about segment boundaries. 794 // talk about segment boundaries.
722 // cf image_for_address from http://svn.digium.com/view/asterisk/team/oej/mini voicemail/dlfcn.c?revision=53912 795 // cf image_for_address from http://svn.digium.com/view/asterisk/team/oej/mini voicemail/dlfcn.c?revision=53912
723 for (; current_image_ >= 0; current_image_--) { 796 for (; current_image_ >= 0; current_image_--) {
724 const mach_header* hdr = _dyld_get_image_header(current_image_); 797 const mach_header* hdr = _dyld_get_image_header(current_image_);
725 if (!hdr) continue; 798 if (!hdr) continue;
726 if (current_load_cmd_ < 0) // set up for this image 799 if (current_load_cmd_ < 0) // set up for this image
727 current_load_cmd_ = hdr->ncmds; // again, go from the top down 800 current_load_cmd_ = hdr->ncmds; // again, go from the top down
728 801
729 // We start with the next load command (we've already looked at this one). 802 // We start with the next load command (we've already looked at this one).
730 for (current_load_cmd_--; current_load_cmd_ >= 0; current_load_cmd_--) { 803 for (current_load_cmd_--; current_load_cmd_ >= 0; current_load_cmd_--) {
731 const char* lc = ((const char *)hdr + sizeof(struct mach_header)); 804 #ifdef MH_MAGIC_64
732 // TODO(csilvers): make this not-quadradic (increment and hold state) 805 if (NextExtMachHelper<MH_MAGIC_64, LC_SEGMENT_64,
733 for (int j = 0; j < current_load_cmd_; j++) // advance to *our* load_cmd 806 struct mach_header_64, struct segment_command_64>(
734 lc += ((const load_command *)lc)->cmdsize; 807 hdr, current_image_, current_load_cmd_,
735 if (((const load_command *)lc)->cmd == LC_SEGMENT) { 808 start, end, flags, offset, inode, filename,
736 const intptr_t dlloff = _dyld_get_image_vmaddr_slide(current_image_); 809 file_mapping, file_pages, anon_mapping,
737 const segment_command* sc = (const segment_command *)lc; 810 anon_pages, dev)) {
738 if (start) *start = sc->vmaddr + dlloff; 811 return true;
739 if (end) *end = sc->vmaddr + sc->vmsize + dlloff; 812 }
740 if (flags) *flags = kDefaultPerms; // can we do better? 813 #endif
741 if (offset) *offset = sc->fileoff; 814 if (NextExtMachHelper<MH_MAGIC, LC_SEGMENT,
742 if (inode) *inode = 0; 815 struct mach_header, struct segment_command>(
743 if (filename) 816 hdr, current_image_, current_load_cmd_,
744 *filename = const_cast<char*>(_dyld_get_image_name(current_image_)); 817 start, end, flags, offset, inode, filename,
745 if (file_mapping) *file_mapping = 0; 818 file_mapping, file_pages, anon_mapping,
746 if (file_pages) *file_pages = 0; // could we use sc->filesize? 819 anon_pages, dev)) {
747 if (anon_mapping) *anon_mapping = 0;
748 if (anon_pages) *anon_pages = 0;
749 if (dev) *dev = 0;
750 return true; 820 return true;
751 } 821 }
752 } 822 }
753 // If we get here, no more load_cmd's in this image talk about 823 // If we get here, no more load_cmd's in this image talk about
754 // segments. Go on to the next image. 824 // segments. Go on to the next image.
755 } 825 }
756 #elif defined(PLATFORM_WINDOWS) 826 #elif defined(PLATFORM_WINDOWS)
757 static char kDefaultPerms[5] = "r-xp"; 827 static char kDefaultPerms[5] = "r-xp";
758 BOOL ok; 828 BOOL ok;
759 if (module_.dwSize == 0) { // only possible before first call 829 if (module_.dwSize == 0) { // only possible before first call
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
838 ProcMapsIterator::Buffer linebuf; 908 ProcMapsIterator::Buffer linebuf;
839 while (it.Next(&start, &end, &flags, &offset, &inode, &filename)) { 909 while (it.Next(&start, &end, &flags, &offset, &inode, &filename)) {
840 int written = it.FormatLine(linebuf.buf_, sizeof(linebuf.buf_), 910 int written = it.FormatLine(linebuf.buf_, sizeof(linebuf.buf_),
841 start, end, flags, offset, inode, filename, 911 start, end, flags, offset, inode, filename,
842 0); 912 0);
843 RawWrite(fd, linebuf.buf_, written); 913 RawWrite(fd, linebuf.buf_, written);
844 } 914 }
845 } 915 }
846 916
847 } // namespace tcmalloc 917 } // 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