mirror of
https://github.com/chromium/crashpad.git
synced 2024-12-27 15:32:10 +08:00
mac handler: Record a file-limits annotation (temporarily)
The "file-limit" annotation will be used to confirm the theory that certain crashes are caused by systems at or near their file descriptor table size limits. The annotation records the system-wide kern.num_files and kern.maxfiles values, and the process-specific current and maximum file descriptor limits. The annotation will be set on crashpad_handler startup, and will be refreshed every time an exception is handled and every time the upload thread processes a pending report. It’s expected that this annotation will be removed after enough data has been collected to confirm the theory. However, the principle is useful enough that we may want to provide this feature more generally under bugs 19 or 21. Bug: crashpad:180 Change-Id: I3bb78fae60e0567bc4ac2625716e0abe0ddae08c Reviewed-on: https://chromium-review.googlesource.com/479914 Reviewed-by: Robert Sesek <rsesek@chromium.org>
This commit is contained in:
parent
ddcc74f08f
commit
b8aaa22905
@ -35,6 +35,10 @@
|
||||
#include "util/net/http_transport.h"
|
||||
#include "util/stdlib/map_insert.h"
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
#include "handler/mac/file_limit_annotation.h"
|
||||
#endif // OS_MACOSX
|
||||
|
||||
namespace crashpad {
|
||||
|
||||
namespace {
|
||||
@ -228,6 +232,10 @@ void CrashReportUploadThread::ProcessPendingReports() {
|
||||
|
||||
void CrashReportUploadThread::ProcessPendingReport(
|
||||
const CrashReportDatabase::Report& report) {
|
||||
#if defined(OS_MACOSX)
|
||||
RecordFileLimitAnnotation();
|
||||
#endif // OS_MACOSX
|
||||
|
||||
Settings* const settings = database_->GetSettings();
|
||||
|
||||
bool uploads_enabled;
|
||||
|
@ -43,6 +43,8 @@
|
||||
'mac/crash_report_exception_handler.h',
|
||||
'mac/exception_handler_server.cc',
|
||||
'mac/exception_handler_server.h',
|
||||
'mac/file_limit_annotation.cc',
|
||||
'mac/file_limit_annotation.h',
|
||||
'prune_crash_reports_thread.cc',
|
||||
'prune_crash_reports_thread.h',
|
||||
'user_stream_data_source.cc',
|
||||
|
@ -61,6 +61,7 @@
|
||||
#include "base/mac/scoped_mach_port.h"
|
||||
#include "handler/mac/crash_report_exception_handler.h"
|
||||
#include "handler/mac/exception_handler_server.h"
|
||||
#include "handler/mac/file_limit_annotation.h"
|
||||
#include "util/mach/child_port_handshake.h"
|
||||
#include "util/mach/mach_extensions.h"
|
||||
#include "util/posix/close_stdio.h"
|
||||
@ -697,6 +698,8 @@ int HandlerMain(int argc,
|
||||
reset_sigterm.reset(&old_sigterm_action);
|
||||
}
|
||||
}
|
||||
|
||||
RecordFileLimitAnnotation();
|
||||
#elif defined(OS_WIN)
|
||||
// Shut down as late as possible relative to programs we're watching.
|
||||
if (!SetProcessShutdownParameters(0x100, SHUTDOWN_NORETRY))
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "base/mac/scoped_mach_port.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
#include "client/settings.h"
|
||||
#include "handler/mac/file_limit_annotation.h"
|
||||
#include "minidump/minidump_file_writer.h"
|
||||
#include "minidump/minidump_user_extension_stream_data_source.h"
|
||||
#include "snapshot/crashpad_info_client_options.h"
|
||||
@ -67,6 +68,7 @@ kern_return_t CrashReportExceptionHandler::CatchMachException(
|
||||
mach_msg_type_number_t* new_state_count,
|
||||
const mach_msg_trailer_t* trailer,
|
||||
bool* destroy_complex_request) {
|
||||
RecordFileLimitAnnotation();
|
||||
Metrics::ExceptionEncountered();
|
||||
Metrics::ExceptionCode(ExceptionCodeForMetrics(exception, code[0]));
|
||||
*destroy_complex_request = true;
|
||||
|
93
handler/mac/file_limit_annotation.cc
Normal file
93
handler/mac/file_limit_annotation.cc
Normal file
@ -0,0 +1,93 @@
|
||||
// Copyright 2017 The Crashpad Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "handler/mac/file_limit_annotation.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/format_macros.h"
|
||||
#include "base/macros.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
#include "client/crashpad_info.h"
|
||||
#include "client/simple_string_dictionary.h"
|
||||
|
||||
namespace {
|
||||
|
||||
// rv is the return value from sysctl() or sysctlbyname(), and value and size
|
||||
// are the pointers passed as oldp and oldlenp. If sysctl() failed, the returned
|
||||
// string will be "E" followed by the error number. If there was a size
|
||||
// mismatch, the returned string will be "Z" followed by the size indicated by
|
||||
// sysctl(). Normally, a string representation of *value will be returned.
|
||||
std::string FormatFromSysctl(int rv, const int* value, const size_t* size) {
|
||||
if (rv != 0) {
|
||||
return base::StringPrintf("E%d", errno);
|
||||
}
|
||||
if (*size != sizeof(*value)) {
|
||||
return base::StringPrintf("Z%zu", *size);
|
||||
}
|
||||
return base::StringPrintf("%d", *value);
|
||||
}
|
||||
|
||||
// Returns a string for |limit|, or "inf" if |limit| is RLIM_INFINITY.
|
||||
std::string StringForRLim(rlim_t limit) {
|
||||
if (limit == RLIM_INFINITY) {
|
||||
return std::string("inf");
|
||||
}
|
||||
|
||||
return base::StringPrintf("%" PRIu64, limit);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace crashpad {
|
||||
|
||||
void RecordFileLimitAnnotation() {
|
||||
CrashpadInfo* crashpad_info = CrashpadInfo::GetCrashpadInfo();
|
||||
SimpleStringDictionary* simple_annotations =
|
||||
crashpad_info->simple_annotations();
|
||||
if (!simple_annotations) {
|
||||
simple_annotations = new SimpleStringDictionary();
|
||||
crashpad_info->set_simple_annotations(simple_annotations);
|
||||
}
|
||||
|
||||
int value;
|
||||
size_t size = sizeof(value);
|
||||
std::string num_files = FormatFromSysctl(
|
||||
sysctlbyname("kern.num_files", &value, &size, nullptr, 0), &value, &size);
|
||||
|
||||
int mib[] = {CTL_KERN, KERN_MAXFILES};
|
||||
size = sizeof(value);
|
||||
std::string max_files = FormatFromSysctl(
|
||||
sysctl(mib, arraysize(mib), &value, &size, nullptr, 0), &value, &size);
|
||||
|
||||
rlimit limit;
|
||||
std::string nofile;
|
||||
if (getrlimit(RLIMIT_NOFILE, &limit) != 0) {
|
||||
nofile = base::StringPrintf("E%d,E%d", errno, errno);
|
||||
} else {
|
||||
nofile =
|
||||
StringForRLim(limit.rlim_cur) + "," + StringForRLim(limit.rlim_max);
|
||||
}
|
||||
|
||||
std::string annotation = base::StringPrintf(
|
||||
"%s,%s,%s", num_files.c_str(), max_files.c_str(), nofile.c_str());
|
||||
simple_annotations->SetKeyValue("file-limits", annotation.c_str());
|
||||
}
|
||||
|
||||
} // namespace crashpad
|
38
handler/mac/file_limit_annotation.h
Normal file
38
handler/mac/file_limit_annotation.h
Normal file
@ -0,0 +1,38 @@
|
||||
// Copyright 2017 The Crashpad Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef CRASHPAD_HANDLER_MAC_FILE_LIMIT_ANNOTATION_H_
|
||||
#define CRASHPAD_HANDLER_MAC_FILE_LIMIT_ANNOTATION_H_
|
||||
|
||||
namespace crashpad {
|
||||
|
||||
//! \brief Records a `"file-limits"` simple annotation for the process.
|
||||
//!
|
||||
//! This annotation will be used to confirm the theory that certain crashes are
|
||||
//! caused by systems at or near their file descriptor table size limits.
|
||||
//!
|
||||
//! The format of the annotation is four comma-separated values: the system-wide
|
||||
//! `kern.num_files` and `kern.maxfiles` values from `sysctl()`, and the
|
||||
//! process-specific current and maximum file descriptor limits from
|
||||
//! `getrlimit(RLIMIT_NOFILE, …)`.
|
||||
//!
|
||||
//! See https://crashpad.chromium.org/bug/180.
|
||||
//!
|
||||
//! TODO(mark): Remove this annotation after sufficient data has been collected
|
||||
//! for analysis.
|
||||
void RecordFileLimitAnnotation();
|
||||
|
||||
} // namespace crashpad
|
||||
|
||||
#endif // CRASHPAD_HANDLER_MAC_FILE_LIMIT_ANNOTATION_H_
|
Loading…
x
Reference in New Issue
Block a user