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

Side by Side Diff: src/platform/crash/crash_dumper.cc

Issue 2128004: Adding in-process crash dumping library and crash uploader (Closed) Base URL: ssh://git@chromiumos-git//chromeos
Patch Set: respond to review and add another test Created 10 years, 7 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 | « src/platform/crash/crash_dumper.h ('k') | src/platform/crash/crash_reporter.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <errno.h>
6 #include <pwd.h>
7 #include <sys/stat.h>
8 #include <sys/types.h>
9 #include <unistd.h>
10
11 #include "base/file_path.h"
12 #include "base/file_util.h"
13 #include "base/logging.h"
14 #include "client/linux/handler/exception_handler.h"
15 #include "common/linux/linux_libc_support.h"
16 #include "common/linux/linux_syscall_support.h"
17 #include "crash/crash_dumper.h"
18
19 // Define sys_mkdir (sys_open passes mode_t as int, so we do too).
20 LSS_INLINE _syscall2(int, mkdir, const char *, pathname, int, mode);
21
22 static const char kDefaultUser[] = "chronos";
23 static const char kSystemCrashParentPath[] = "/var/spool";
24 static const char kSystemCrashPath[] = "/var/spool/crash";
25 static const char kUserCrashParentPath[] = "/home/chronos/user";
26 static const char kUserCrashPath[] = "/home/chronos/user/crash";
27
28 // Pointers to paths, set when crash dumping is enabled.
29 static const char *s_crash_path;
30 static const char *s_crash_parent_path;
31 static mode_t s_dump_directory_mode;
32
33 static bool s_any_crashes_occurred = false;
34 static scoped_ptr<google_breakpad::ExceptionHandler> s_breakpad_handler;
35
36 static bool s_enabled = false;
37
38
39 // Prepare the crash path. Must avoid allocating memory.
40 static bool PrepareCrashPath() {
41 struct kernel_stat buf;
42 if (sys_stat(s_crash_path, &buf) < 0) {
43 // Dump directory does not exist, so create it and its parent now,
44 // at the time of the crash.
45 sys_mkdir(s_crash_parent_path, 755);
46 sys_mkdir(s_crash_path, s_dump_directory_mode);
47 }
48 return sys_stat(s_crash_path, &buf) == 0;
49 }
50
51 // Use FilterCallback to avoid recursive crashing.
52 // TODO(kmixter): Also use it to avoid enqueuing too many crash dumps
53 // system wide - if we get in a crash/restart loop we don't want the entire
54 // stateful partition to be filled up.
55 static bool FilterCallback(void *) {
56 // This function runs in a compromised context - a crash has already
57 // occurred so memory allocation and libc should be avoided.
58 bool old_any_crashes_occured = s_any_crashes_occurred;
59 s_any_crashes_occurred = true;
60 // The crash path may have been removed or mounted-over, so make sure
61 // there is a container directory. If it fails, not much we can do.
62 PrepareCrashPath();
63 return !old_any_crashes_occured;
64 }
65
66 static bool GetEffectiveUser(std::string *result) {
67 char storage[256];
68 struct passwd passwd_storage;
69 struct passwd *passwd_result = NULL;
70
71 if (getpwuid_r(geteuid(), &passwd_storage, storage, sizeof(storage),
72 &passwd_result) != 0 || passwd_result == NULL) {
73 return false;
74 }
75
76 *result = passwd_result->pw_name;
77 return true;
78 }
79
80 void CrashDumper::Enable() {
81 CHECK(!s_enabled) << "Crash handling already enabled";
82
83 std::string name;
84 CHECK(GetEffectiveUser(&name))
85 << "getpwuid_r failed - " << errno
86 << " - crash reporting cannot be enabled";
87
88 if (name == kDefaultUser) {
89 // Crashes as "chronos" when the user is not yet logged in will
90 // still be recorded to /home/chronos/user/crash in the
91 // stateful partition (outside cryptohome). These will eventually
92 // be uploaded when no user is logged in.
93 s_crash_path = kUserCrashPath;
94 s_crash_parent_path = kUserCrashParentPath;
95 s_dump_directory_mode = 0755;
96 } else {
97 s_crash_path = kSystemCrashPath;
98 s_crash_parent_path = kSystemCrashParentPath;
99 // Make the dump directory sticky so any UID can write to
100 // it but not remove another UID's crashes.
101 s_dump_directory_mode = 01777;
102 }
103
104 CHECK(PrepareCrashPath()) << "Unable to create path " << s_crash_path;
105
106 // Begin collecting crashes
107 s_breakpad_handler.reset(new google_breakpad::ExceptionHandler(
108 s_crash_path,
109 FilterCallback,
110 NULL, // No minidump callback - sending happens asynchronously to writing
111 NULL, // No callback context necessary
112 true)); // Install handler now.
113
114 s_enabled = true;
115 }
116
117 bool CrashDumper::IsEnabled() {
118 return s_enabled;
119 }
120
121 void CrashDumper::Disable() {
122 CHECK(s_enabled) << "Crash handling was not enabled";
123 s_breakpad_handler.reset(NULL);
124 s_crash_path = NULL;
125 s_crash_parent_path = NULL;
126 s_enabled = false;
127 }
OLDNEW
« no previous file with comments | « src/platform/crash/crash_dumper.h ('k') | src/platform/crash/crash_reporter.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698