| 613 | |
| 614 | |
| 615 | void Application::AttachDebugger(const String& filename, bool interactive) |
| 616 | { |
| 617 | #ifndef _WIN32 |
| 618 | #ifdef __linux__ |
| 619 | prctl(PR_SET_DUMPABLE, 1); |
| 620 | #endif /* __linux __ */ |
| 621 | |
| 622 | String my_pid = Convert::ToString(Utility::GetPid()); |
| 623 | |
| 624 | pid_t pid = fork(); |
| 625 | |
| 626 | if (pid < 0) { |
| 627 | BOOST_THROW_EXCEPTION(posix_error() |
| 628 | << boost::errinfo_api_function("fork") |
| 629 | << boost::errinfo_errno(errno)); |
| 630 | } |
| 631 | |
| 632 | if (pid == 0) { |
| 633 | if (!interactive) { |
| 634 | int fd = open(filename.CStr(), O_CREAT | O_RDWR | O_APPEND, 0600); |
| 635 | |
| 636 | if (fd < 0) { |
| 637 | BOOST_THROW_EXCEPTION(posix_error() |
| 638 | << boost::errinfo_api_function("open") |
| 639 | << boost::errinfo_errno(errno) |
| 640 | << boost::errinfo_file_name(filename)); |
| 641 | } |
| 642 | |
| 643 | if (fd != 1) { |
| 644 | /* redirect stdout to the file */ |
| 645 | dup2(fd, 1); |
| 646 | close(fd); |
| 647 | } |
| 648 | |
| 649 | /* redirect stderr to stdout */ |
| 650 | if (fd != 2) |
| 651 | close(2); |
| 652 | |
| 653 | dup2(1, 2); |
| 654 | } |
| 655 | |
| 656 | char **argv; |
| 657 | char *my_pid_str = strdup(my_pid.CStr()); |
| 658 | |
| 659 | if (interactive) { |
| 660 | const char *uargv[] = { |
| 661 | "gdb", |
| 662 | "-p", |
| 663 | my_pid_str, |
| 664 | nullptr |
| 665 | }; |
| 666 | |
| 667 | argv = const_cast<char **>(uargv); |
| 668 | |
| 669 | (void) execvp(argv[0], argv); |
| 670 | } else { |
| 671 | const char *uargv[] = { |
| 672 | "gdb", |
nothing calls this directly
no test coverage detected