mirror of
https://github.com/yuzu-emu/breakpad.git
synced 2025-08-04 21:41:01 +00:00
Make the Linux CrashGenerationClient an interface.
Also allow it to be set on the ExceptionHandler. This will allow Chromium's implementation to be properly treated as an out-of-process handler. BUG=https://code.google.com/p/chromium/issues/detail?id=349600 R=mark@chromium.org Review URL: https://breakpad.appspot.com/2664002 git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1324 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
parent
c96f4d7e01
commit
44ba0b2050
|
@ -27,37 +27,41 @@
|
||||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
#include "client/linux/crash_generation/crash_generation_client.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#include "client/linux/crash_generation/crash_generation_client.h"
|
|
||||||
#include "common/linux/eintr_wrapper.h"
|
#include "common/linux/eintr_wrapper.h"
|
||||||
#include "common/linux/ignore_ret.h"
|
#include "common/linux/ignore_ret.h"
|
||||||
#include "common/linux/linux_libc_support.h"
|
|
||||||
#include "third_party/lss/linux_syscall_support.h"
|
#include "third_party/lss/linux_syscall_support.h"
|
||||||
|
|
||||||
namespace google_breakpad {
|
namespace google_breakpad {
|
||||||
|
|
||||||
bool
|
namespace {
|
||||||
CrashGenerationClient::RequestDump(const void* blob, size_t blob_size)
|
|
||||||
{
|
class CrashGenerationClientImpl : public CrashGenerationClient {
|
||||||
|
public:
|
||||||
|
explicit CrashGenerationClientImpl(int server_fd) : server_fd_(server_fd) {}
|
||||||
|
virtual ~CrashGenerationClientImpl() {}
|
||||||
|
|
||||||
|
virtual bool RequestDump(const void* blob, size_t blob_size) {
|
||||||
int fds[2];
|
int fds[2];
|
||||||
sys_socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
|
if (sys_socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0)
|
||||||
|
return false;
|
||||||
static const unsigned kControlMsgSize = CMSG_SPACE(sizeof(int));
|
static const unsigned kControlMsgSize = CMSG_SPACE(sizeof(int));
|
||||||
|
|
||||||
struct kernel_msghdr msg;
|
struct kernel_iovec iov;
|
||||||
my_memset(&msg, 0, sizeof(struct kernel_msghdr));
|
iov.iov_base = const_cast<void*>(blob);
|
||||||
struct kernel_iovec iov[1];
|
iov.iov_len = blob_size;
|
||||||
iov[0].iov_base = const_cast<void*>(blob);
|
|
||||||
iov[0].iov_len = blob_size;
|
|
||||||
|
|
||||||
msg.msg_iov = iov;
|
struct kernel_msghdr msg = { 0 };
|
||||||
msg.msg_iovlen = sizeof(iov) / sizeof(iov[0]);
|
msg.msg_iov = &iov;
|
||||||
char cmsg[kControlMsgSize];
|
msg.msg_iovlen = 1;
|
||||||
my_memset(cmsg, 0, kControlMsgSize);
|
char cmsg[kControlMsgSize] = "";
|
||||||
msg.msg_control = cmsg;
|
msg.msg_control = cmsg;
|
||||||
msg.msg_controllen = sizeof(cmsg);
|
msg.msg_controllen = sizeof(cmsg);
|
||||||
|
|
||||||
|
@ -70,23 +74,30 @@ CrashGenerationClient::RequestDump(const void* blob, size_t blob_size)
|
||||||
|
|
||||||
ssize_t ret = HANDLE_EINTR(sys_sendmsg(server_fd_, &msg, 0));
|
ssize_t ret = HANDLE_EINTR(sys_sendmsg(server_fd_, &msg, 0));
|
||||||
sys_close(fds[1]);
|
sys_close(fds[1]);
|
||||||
if (ret <= 0)
|
if (ret < 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// wait for an ACK from the server
|
// Wait for an ACK from the server.
|
||||||
char b;
|
char b;
|
||||||
IGNORE_RET(HANDLE_EINTR(sys_read(fds[0], &b, 1)));
|
IGNORE_RET(HANDLE_EINTR(sys_read(fds[0], &b, 1)));
|
||||||
|
sys_close(fds[0]);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//static
|
private:
|
||||||
CrashGenerationClient*
|
int server_fd_;
|
||||||
CrashGenerationClient::TryCreate(int server_fd)
|
|
||||||
{
|
DISALLOW_COPY_AND_ASSIGN(CrashGenerationClientImpl);
|
||||||
if (0 > server_fd)
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
// static
|
||||||
|
CrashGenerationClient* CrashGenerationClient::TryCreate(int server_fd) {
|
||||||
|
if (server_fd < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
return new CrashGenerationClient(server_fd);
|
return new CrashGenerationClientImpl(server_fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace google_breakpad
|
||||||
|
|
|
@ -30,38 +30,34 @@
|
||||||
#ifndef CLIENT_LINUX_CRASH_GENERATION_CRASH_GENERATION_CLIENT_H_
|
#ifndef CLIENT_LINUX_CRASH_GENERATION_CRASH_GENERATION_CLIENT_H_
|
||||||
#define CLIENT_LINUX_CRASH_GENERATION_CRASH_GENERATION_CLIENT_H_
|
#define CLIENT_LINUX_CRASH_GENERATION_CRASH_GENERATION_CLIENT_H_
|
||||||
|
|
||||||
|
#include "common/basictypes.h"
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
namespace google_breakpad {
|
namespace google_breakpad {
|
||||||
|
|
||||||
|
// CrashGenerationClient is an interface for implementing out-of-process crash
|
||||||
|
// dumping. The default implementation, accessed via the TryCreate() factory,
|
||||||
|
// works in conjunction with the CrashGenerationServer to generate a minidump
|
||||||
|
// via a remote process.
|
||||||
class CrashGenerationClient {
|
class CrashGenerationClient {
|
||||||
public:
|
public:
|
||||||
~CrashGenerationClient()
|
CrashGenerationClient() {}
|
||||||
{
|
virtual ~CrashGenerationClient() {}
|
||||||
}
|
|
||||||
|
|
||||||
// Request the crash server to generate a dump. |blob| is a hack,
|
// Request the crash server to generate a dump. |blob| is an opaque
|
||||||
// see exception_handler.h and minidump_writer.h
|
// CrashContext pointer from exception_handler.h.
|
||||||
//
|
// Returns true if the dump was successful; false otherwise.
|
||||||
// Return true if the dump was successful; false otherwise.
|
virtual bool RequestDump(const void* blob, size_t blob_size) = 0;
|
||||||
bool RequestDump(const void* blob, size_t blob_size);
|
|
||||||
|
|
||||||
// Return a new CrashGenerationClient if |server_fd| is valid and
|
// Returns a new CrashGenerationClient if |server_fd| is valid and
|
||||||
// connects to a CrashGenerationServer. Otherwise, return NULL.
|
// connects to a CrashGenerationServer. Otherwise, return NULL.
|
||||||
// The returned CrashGenerationClient* is owned by the caller of
|
// The returned CrashGenerationClient* is owned by the caller of
|
||||||
// this function.
|
// this function.
|
||||||
static CrashGenerationClient* TryCreate(int server_fd);
|
static CrashGenerationClient* TryCreate(int server_fd);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CrashGenerationClient(int server_fd) : server_fd_(server_fd)
|
DISALLOW_COPY_AND_ASSIGN(CrashGenerationClient);
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
int server_fd_;
|
|
||||||
|
|
||||||
// prevent copy construction and assignment
|
|
||||||
CrashGenerationClient(const CrashGenerationClient&);
|
|
||||||
CrashGenerationClient& operator=(const CrashGenerationClient&);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace google_breakpad
|
} // namespace google_breakpad
|
||||||
|
|
|
@ -146,6 +146,10 @@ class ExceptionHandler {
|
||||||
crash_handler_ = callback;
|
crash_handler_ = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_crash_generation_client(CrashGenerationClient* client) {
|
||||||
|
crash_generation_client_.reset(client);
|
||||||
|
}
|
||||||
|
|
||||||
// Writes a minidump immediately. This can be used to capture the execution
|
// Writes a minidump immediately. This can be used to capture the execution
|
||||||
// state independently of a crash.
|
// state independently of a crash.
|
||||||
// Returns true on success.
|
// Returns true on success.
|
||||||
|
|
Loading…
Reference in a new issue