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

Side by Side Diff: base/debug/stack_trace_posix.cc

Issue 1284083002: Print stack traces in child processes when browser tests failed. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: more fixes Created 5 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
« no previous file with comments | « base/debug/stack_trace.h ('k') | base/debug/stack_trace_win.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "base/debug/stack_trace.h" 5 #include "base/debug/stack_trace.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #include <fcntl.h> 8 #include <fcntl.h>
9 #include <signal.h> 9 #include <signal.h>
10 #include <stdio.h> 10 #include <stdio.h>
(...skipping 494 matching lines...) Expand 10 before | Expand all | Expand 10 after
505 } 505 }
506 506
507 // Returns a O_RDONLY file descriptor for |file_path| if it was opened 507 // Returns a O_RDONLY file descriptor for |file_path| if it was opened
508 // sucessfully during the initialization. The file is repositioned at 508 // sucessfully during the initialization. The file is repositioned at
509 // offset 0. 509 // offset 0.
510 // IMPORTANT: This function must be async-signal-safe because it can be 510 // IMPORTANT: This function must be async-signal-safe because it can be
511 // called from a signal handler (symbolizing stack frames for a crash). 511 // called from a signal handler (symbolizing stack frames for a crash).
512 int GetFileDescriptor(const char* file_path) { 512 int GetFileDescriptor(const char* file_path) {
513 int fd = -1; 513 int fd = -1;
514 514
515 #if !defined(NDEBUG) 515 #if !defined(OFFICIAL_BUILD)
516 if (file_path) { 516 if (file_path) {
517 // The assumption here is that iterating over std::map<std::string, int> 517 // The assumption here is that iterating over std::map<std::string, int>
518 // using a const_iterator does not allocate dynamic memory, hense it is 518 // using a const_iterator does not allocate dynamic memory, hense it is
519 // async-signal-safe. 519 // async-signal-safe.
520 std::map<std::string, int>::const_iterator it; 520 std::map<std::string, int>::const_iterator it;
521 for (it = modules_.begin(); it != modules_.end(); ++it) { 521 for (it = modules_.begin(); it != modules_.end(); ++it) {
522 if (strcmp((it->first).c_str(), file_path) == 0) { 522 if (strcmp((it->first).c_str(), file_path) == 0) {
523 // POSIX.1-2004 requires an implementation to guarantee that dup() 523 // POSIX.1-2004 requires an implementation to guarantee that dup()
524 // is async-signal-safe. 524 // is async-signal-safe.
525 fd = dup(it->second); 525 fd = dup(it->second);
526 break; 526 break;
527 } 527 }
528 } 528 }
529 // POSIX.1-2004 requires an implementation to guarantee that lseek() 529 // POSIX.1-2004 requires an implementation to guarantee that lseek()
530 // is async-signal-safe. 530 // is async-signal-safe.
531 if (fd >= 0 && lseek(fd, 0, SEEK_SET) < 0) { 531 if (fd >= 0 && lseek(fd, 0, SEEK_SET) < 0) {
532 // Failed to seek. 532 // Failed to seek.
533 fd = -1; 533 fd = -1;
534 } 534 }
535 } 535 }
536 #endif // !defined(NDEBUG) 536 #endif // !defined(OFFICIAL_BUILD)
537 537
538 return fd; 538 return fd;
539 } 539 }
540 540
541 // Searches for the object file (from /proc/self/maps) that contains 541 // Searches for the object file (from /proc/self/maps) that contains
542 // the specified pc. If found, sets |start_address| to the start address 542 // the specified pc. If found, sets |start_address| to the start address
543 // of where this object file is mapped in memory, sets the module base 543 // of where this object file is mapped in memory, sets the module base
544 // address into |base_address|, copies the object file name into 544 // address into |base_address|, copies the object file name into
545 // |out_file_name|, and attempts to open the object file. If the object 545 // |out_file_name|, and attempts to open the object file. If the object
546 // file is opened successfully, returns the file descriptor. Otherwise, 546 // file is opened successfully, returns the file descriptor. Otherwise,
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
612 return false; 612 return false;
613 } 613 }
614 614
615 is_initialized_ = true; 615 is_initialized_ = true;
616 return true; 616 return true;
617 } 617 }
618 618
619 // Opens all object files and caches their file descriptors. 619 // Opens all object files and caches their file descriptors.
620 void OpenSymbolFiles() { 620 void OpenSymbolFiles() {
621 // Pre-opening and caching the file descriptors of all loaded modules is 621 // Pre-opening and caching the file descriptors of all loaded modules is
622 // not considered safe for retail builds. Hence it is only done in debug 622 // not safe for production builds. Hence it is only done in non-official
623 // builds. For more details, take a look at: http://crbug.com/341966 623 // builds. For more details, take a look at: http://crbug.com/341966.
624 // Enabling this to release mode would require approval from the security 624 #if !defined(OFFICIAL_BUILD)
625 // team.
626 #if !defined(NDEBUG)
627 // Open the object files for all read-only executable regions and cache 625 // Open the object files for all read-only executable regions and cache
628 // their file descriptors. 626 // their file descriptors.
629 std::vector<MappedMemoryRegion>::const_iterator it; 627 std::vector<MappedMemoryRegion>::const_iterator it;
630 for (it = regions_.begin(); it != regions_.end(); ++it) { 628 for (it = regions_.begin(); it != regions_.end(); ++it) {
631 const MappedMemoryRegion& region = *it; 629 const MappedMemoryRegion& region = *it;
632 // Only interesed in read-only executable regions. 630 // Only interesed in read-only executable regions.
633 if ((region.permissions & MappedMemoryRegion::READ) == 631 if ((region.permissions & MappedMemoryRegion::READ) ==
634 MappedMemoryRegion::READ && 632 MappedMemoryRegion::READ &&
635 (region.permissions & MappedMemoryRegion::WRITE) == 0 && 633 (region.permissions & MappedMemoryRegion::WRITE) == 0 &&
636 (region.permissions & MappedMemoryRegion::EXECUTE) == 634 (region.permissions & MappedMemoryRegion::EXECUTE) ==
(...skipping 11 matching lines...) Expand all
648 int fd = open(region.path.c_str(), O_RDONLY | O_CLOEXEC); 646 int fd = open(region.path.c_str(), O_RDONLY | O_CLOEXEC);
649 if (fd >= 0) { 647 if (fd >= 0) {
650 modules_.insert(std::make_pair(region.path, fd)); 648 modules_.insert(std::make_pair(region.path, fd));
651 } else { 649 } else {
652 LOG(WARNING) << "Failed to open file: " << region.path 650 LOG(WARNING) << "Failed to open file: " << region.path
653 << "\n Error: " << strerror(errno); 651 << "\n Error: " << strerror(errno);
654 } 652 }
655 } 653 }
656 } 654 }
657 } 655 }
658 #endif // !defined(NDEBUG) 656 #endif // !defined(OFFICIAL_BUILD)
659 } 657 }
660 658
661 // Initializes and installs the symbolization callback. 659 // Initializes and installs the symbolization callback.
662 void Init() { 660 void Init() {
663 if (CacheMemoryRegions()) { 661 if (CacheMemoryRegions()) {
664 OpenSymbolFiles(); 662 OpenSymbolFiles();
665 google::InstallSymbolizeOpenObjectFileCallback( 663 google::InstallSymbolizeOpenObjectFileCallback(
666 &OpenObjectFileContainingPc); 664 &OpenObjectFileContainingPc);
667 } 665 }
668 } 666 }
669 667
670 // Unregister symbolization callback. 668 // Unregister symbolization callback.
671 void UnregisterCallback() { 669 void UnregisterCallback() {
672 if (is_initialized_) { 670 if (is_initialized_) {
673 google::InstallSymbolizeOpenObjectFileCallback(NULL); 671 google::InstallSymbolizeOpenObjectFileCallback(NULL);
674 is_initialized_ = false; 672 is_initialized_ = false;
675 } 673 }
676 } 674 }
677 675
678 // Closes all file descriptors owned by this instance. 676 // Closes all file descriptors owned by this instance.
679 void CloseObjectFiles() { 677 void CloseObjectFiles() {
680 #if !defined(NDEBUG) 678 #if !defined(OFFICIAL_BUILD)
681 std::map<std::string, int>::iterator it; 679 std::map<std::string, int>::iterator it;
682 for (it = modules_.begin(); it != modules_.end(); ++it) { 680 for (it = modules_.begin(); it != modules_.end(); ++it) {
683 int ret = IGNORE_EINTR(close(it->second)); 681 int ret = IGNORE_EINTR(close(it->second));
684 DCHECK(!ret); 682 DCHECK(!ret);
685 it->second = -1; 683 it->second = -1;
686 } 684 }
687 modules_.clear(); 685 modules_.clear();
688 #endif // !defined(NDEBUG) 686 #endif // !defined(OFFICIAL_BUILD)
689 } 687 }
690 688
691 // Set to true upon successful initialization. 689 // Set to true upon successful initialization.
692 bool is_initialized_; 690 bool is_initialized_;
693 691
694 #if !defined(NDEBUG) 692 #if !defined(OFFICIAL_BUILD)
695 // Mapping from file name to file descriptor. Includes file descriptors 693 // Mapping from file name to file descriptor. Includes file descriptors
696 // for all successfully opened object files and the file descriptor for 694 // for all successfully opened object files and the file descriptor for
697 // /proc/self/maps. This code is not safe for release builds so 695 // /proc/self/maps. This code is not safe for production builds.
698 // this is only done for DEBUG builds.
699 std::map<std::string, int> modules_; 696 std::map<std::string, int> modules_;
700 #endif // !defined(NDEBUG) 697 #endif // !defined(OFFICIAL_BUILD)
701 698
702 // Cache for the process memory regions. Produced by parsing the contents 699 // Cache for the process memory regions. Produced by parsing the contents
703 // of /proc/self/maps cache. 700 // of /proc/self/maps cache.
704 std::vector<MappedMemoryRegion> regions_; 701 std::vector<MappedMemoryRegion> regions_;
705 702
706 DISALLOW_COPY_AND_ASSIGN(SandboxSymbolizeHelper); 703 DISALLOW_COPY_AND_ASSIGN(SandboxSymbolizeHelper);
707 }; 704 };
708 #endif // USE_SYMBOLIZE 705 #endif // USE_SYMBOLIZE
709 706
710 bool EnableInProcessStackDumpingForSandbox() { 707 bool EnableInProcessStackDumpingForSandbox() {
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
838 *ptr = *start; 835 *ptr = *start;
839 *start++ = ch; 836 *start++ = ch;
840 } 837 }
841 return buf; 838 return buf;
842 } 839 }
843 840
844 } // namespace internal 841 } // namespace internal
845 842
846 } // namespace debug 843 } // namespace debug
847 } // namespace base 844 } // namespace base
OLDNEW
« no previous file with comments | « base/debug/stack_trace.h ('k') | base/debug/stack_trace_win.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698