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

Side by Side Diff: base/process/launch_posix.cc

Issue 1291553003: Print stack traces in child processes when browser tests failed. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: patch 1295823002 which fixes the console coming up on Win8+ and adds regression tests 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
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/process/launch.h" 5 #include "base/process/launch.h"
6 6
7 #include <dirent.h> 7 #include <dirent.h>
8 #include <errno.h> 8 #include <errno.h>
9 #include <fcntl.h> 9 #include <fcntl.h>
10 #include <sched.h> 10 #include <sched.h>
(...skipping 512 matching lines...) Expand 10 before | Expand all | Expand 10 after
523 EXECUTE_FAILURE, 523 EXECUTE_FAILURE,
524 EXECUTE_SUCCESS, 524 EXECUTE_SUCCESS,
525 GOT_MAX_OUTPUT, 525 GOT_MAX_OUTPUT,
526 }; 526 };
527 527
528 // Executes the application specified by |argv| and wait for it to exit. Stores 528 // Executes the application specified by |argv| and wait for it to exit. Stores
529 // the output (stdout) in |output|. If |do_search_path| is set, it searches the 529 // the output (stdout) in |output|. If |do_search_path| is set, it searches the
530 // path for the application; in that case, |envp| must be null, and it will use 530 // path for the application; in that case, |envp| must be null, and it will use
531 // the current environment. If |do_search_path| is false, |argv[0]| should fully 531 // the current environment. If |do_search_path| is false, |argv[0]| should fully
532 // specify the path of the application, and |envp| will be used as the 532 // specify the path of the application, and |envp| will be used as the
533 // environment. Redirects stderr to /dev/null. 533 // environment. If |include_stderr| is true, includes stderr otherwise redirects
534 // it to /dev/null.
534 // If we successfully start the application and get all requested output, we 535 // If we successfully start the application and get all requested output, we
535 // return GOT_MAX_OUTPUT, or if there is a problem starting or exiting 536 // return GOT_MAX_OUTPUT, or if there is a problem starting or exiting
536 // the application we return RUN_FAILURE. Otherwise we return EXECUTE_SUCCESS. 537 // the application we return RUN_FAILURE. Otherwise we return EXECUTE_SUCCESS.
537 // The GOT_MAX_OUTPUT return value exists so a caller that asks for limited 538 // The GOT_MAX_OUTPUT return value exists so a caller that asks for limited
538 // output can treat this as a success, despite having an exit code of SIG_PIPE 539 // output can treat this as a success, despite having an exit code of SIG_PIPE
539 // due to us closing the output pipe. 540 // due to us closing the output pipe.
540 // In the case of EXECUTE_SUCCESS, the application exit code will be returned 541 // In the case of EXECUTE_SUCCESS, the application exit code will be returned
541 // in |*exit_code|, which should be checked to determine if the application 542 // in |*exit_code|, which should be checked to determine if the application
542 // ran successfully. 543 // ran successfully.
543 static GetAppOutputInternalResult GetAppOutputInternal( 544 static GetAppOutputInternalResult GetAppOutputInternal(
544 const std::vector<std::string>& argv, 545 const std::vector<std::string>& argv,
545 char* const envp[], 546 char* const envp[],
547 bool include_stderr,
546 std::string* output, 548 std::string* output,
547 size_t max_output, 549 size_t max_output,
548 bool do_search_path, 550 bool do_search_path,
549 int* exit_code) { 551 int* exit_code) {
550 // Doing a blocking wait for another command to finish counts as IO. 552 // Doing a blocking wait for another command to finish counts as IO.
551 base::ThreadRestrictions::AssertIOAllowed(); 553 base::ThreadRestrictions::AssertIOAllowed();
552 // exit_code must be supplied so calling function can determine success. 554 // exit_code must be supplied so calling function can determine success.
553 DCHECK(exit_code); 555 DCHECK(exit_code);
554 *exit_code = EXIT_FAILURE; 556 *exit_code = EXIT_FAILURE;
555 557
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
590 int dev_null = open("/dev/null", O_WRONLY); 592 int dev_null = open("/dev/null", O_WRONLY);
591 if (dev_null < 0) 593 if (dev_null < 0)
592 _exit(127); 594 _exit(127);
593 595
594 // Stop type-profiler. 596 // Stop type-profiler.
595 // The profiler should be stopped between fork and exec since it inserts 597 // The profiler should be stopped between fork and exec since it inserts
596 // locks at new/delete expressions. See http://crbug.com/36678. 598 // locks at new/delete expressions. See http://crbug.com/36678.
597 base::type_profiler::Controller::Stop(); 599 base::type_profiler::Controller::Stop();
598 600
599 fd_shuffle1.push_back(InjectionArc(pipe_fd[1], STDOUT_FILENO, true)); 601 fd_shuffle1.push_back(InjectionArc(pipe_fd[1], STDOUT_FILENO, true));
600 fd_shuffle1.push_back(InjectionArc(dev_null, STDERR_FILENO, true)); 602 fd_shuffle1.push_back(InjectionArc(
603 include_stderr ? pipe_fd[1] : dev_null,
604 STDERR_FILENO, true));
601 fd_shuffle1.push_back(InjectionArc(dev_null, STDIN_FILENO, true)); 605 fd_shuffle1.push_back(InjectionArc(dev_null, STDIN_FILENO, true));
602 // Adding another element here? Remeber to increase the argument to 606 // Adding another element here? Remeber to increase the argument to
603 // reserve(), above. 607 // reserve(), above.
604 608
605 for (size_t i = 0; i < fd_shuffle1.size(); ++i) 609 for (size_t i = 0; i < fd_shuffle1.size(); ++i)
606 fd_shuffle2.push_back(fd_shuffle1[i]); 610 fd_shuffle2.push_back(fd_shuffle1[i]);
607 611
608 if (!ShuffleFileDescriptors(&fd_shuffle1)) 612 if (!ShuffleFileDescriptors(&fd_shuffle1))
609 _exit(127); 613 _exit(127);
610 614
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
659 } 663 }
660 664
661 bool GetAppOutput(const CommandLine& cl, std::string* output) { 665 bool GetAppOutput(const CommandLine& cl, std::string* output) {
662 return GetAppOutput(cl.argv(), output); 666 return GetAppOutput(cl.argv(), output);
663 } 667 }
664 668
665 bool GetAppOutput(const std::vector<std::string>& argv, std::string* output) { 669 bool GetAppOutput(const std::vector<std::string>& argv, std::string* output) {
666 // Run |execve()| with the current environment and store "unlimited" data. 670 // Run |execve()| with the current environment and store "unlimited" data.
667 int exit_code; 671 int exit_code;
668 GetAppOutputInternalResult result = GetAppOutputInternal( 672 GetAppOutputInternalResult result = GetAppOutputInternal(
669 argv, NULL, output, std::numeric_limits<std::size_t>::max(), true, 673 argv, NULL, false, output, std::numeric_limits<std::size_t>::max(), true,
670 &exit_code); 674 &exit_code);
671 return result == EXECUTE_SUCCESS && exit_code == EXIT_SUCCESS; 675 return result == EXECUTE_SUCCESS && exit_code == EXIT_SUCCESS;
672 } 676 }
673 677
678 bool GetAppOutputAndError(const CommandLine& cl, std::string* output) {
679 // Run |execve()| with the current environment and store "unlimited" data.
680 int exit_code;
681 GetAppOutputInternalResult result = GetAppOutputInternal(
682 cl.argv(), NULL, true, output, std::numeric_limits<std::size_t>::max(),
683 true, &exit_code);
684 return result == EXECUTE_SUCCESS && exit_code == EXIT_SUCCESS;
685 }
686
674 // TODO(viettrungluu): Conceivably, we should have a timeout as well, so we 687 // TODO(viettrungluu): Conceivably, we should have a timeout as well, so we
675 // don't hang if what we're calling hangs. 688 // don't hang if what we're calling hangs.
676 bool GetAppOutputRestricted(const CommandLine& cl, 689 bool GetAppOutputRestricted(const CommandLine& cl,
677 std::string* output, size_t max_output) { 690 std::string* output, size_t max_output) {
678 // Run |execve()| with the empty environment. 691 // Run |execve()| with the empty environment.
679 char* const empty_environ = NULL; 692 char* const empty_environ = NULL;
680 int exit_code; 693 int exit_code;
681 GetAppOutputInternalResult result = GetAppOutputInternal( 694 GetAppOutputInternalResult result = GetAppOutputInternal(
682 cl.argv(), &empty_environ, output, max_output, false, &exit_code); 695 cl.argv(), &empty_environ, false, output, max_output, false, &exit_code);
683 return result == GOT_MAX_OUTPUT || (result == EXECUTE_SUCCESS && 696 return result == GOT_MAX_OUTPUT || (result == EXECUTE_SUCCESS &&
684 exit_code == EXIT_SUCCESS); 697 exit_code == EXIT_SUCCESS);
685 } 698 }
686 699
687 bool GetAppOutputWithExitCode(const CommandLine& cl, 700 bool GetAppOutputWithExitCode(const CommandLine& cl,
688 std::string* output, 701 std::string* output,
689 int* exit_code) { 702 int* exit_code) {
690 // Run |execve()| with the current environment and store "unlimited" data. 703 // Run |execve()| with the current environment and store "unlimited" data.
691 GetAppOutputInternalResult result = GetAppOutputInternal( 704 GetAppOutputInternalResult result = GetAppOutputInternal(
692 cl.argv(), NULL, output, std::numeric_limits<std::size_t>::max(), true, 705 cl.argv(), NULL, false, output, std::numeric_limits<std::size_t>::max(),
693 exit_code); 706 true, exit_code);
694 return result == EXECUTE_SUCCESS; 707 return result == EXECUTE_SUCCESS;
695 } 708 }
696 709
697 #endif // !defined(OS_NACL_NONSFI) 710 #endif // !defined(OS_NACL_NONSFI)
698 711
699 #if defined(OS_LINUX) || defined(OS_NACL_NONSFI) 712 #if defined(OS_LINUX) || defined(OS_NACL_NONSFI)
700 namespace { 713 namespace {
701 714
702 bool IsRunningOnValgrind() { 715 bool IsRunningOnValgrind() {
703 return RUNNING_ON_VALGRIND; 716 return RUNNING_ON_VALGRIND;
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
781 jmp_buf env; 794 jmp_buf env;
782 if (setjmp(env) == 0) { 795 if (setjmp(env) == 0) {
783 return CloneAndLongjmpInChild(flags, ptid, ctid, &env); 796 return CloneAndLongjmpInChild(flags, ptid, ctid, &env);
784 } 797 }
785 798
786 return 0; 799 return 0;
787 } 800 }
788 #endif // defined(OS_LINUX) || defined(OS_NACL_NONSFI) 801 #endif // defined(OS_LINUX) || defined(OS_NACL_NONSFI)
789 802
790 } // namespace base 803 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698