From 44ba0b2050f22376d623663652395de079a4b713 Mon Sep 17 00:00:00 2001 From: "rsesek@chromium.org" Date: Mon, 5 May 2014 20:36:06 +0000 Subject: 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 --- .../crash_generation/crash_generation_client.cc | 105 ++++++++++++--------- 1 file changed, 58 insertions(+), 47 deletions(-) (limited to 'src/client/linux/crash_generation/crash_generation_client.cc') diff --git a/src/client/linux/crash_generation/crash_generation_client.cc b/src/client/linux/crash_generation/crash_generation_client.cc index 6ede7791..aed13e14 100644 --- a/src/client/linux/crash_generation/crash_generation_client.cc +++ b/src/client/linux/crash_generation/crash_generation_client.cc @@ -27,66 +27,77 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#include "client/linux/crash_generation/crash_generation_client.h" + #include #include #include #include -#include "client/linux/crash_generation/crash_generation_client.h" #include "common/linux/eintr_wrapper.h" #include "common/linux/ignore_ret.h" -#include "common/linux/linux_libc_support.h" #include "third_party/lss/linux_syscall_support.h" namespace google_breakpad { -bool -CrashGenerationClient::RequestDump(const void* blob, size_t blob_size) -{ - int fds[2]; - sys_socketpair(AF_UNIX, SOCK_STREAM, 0, fds); - static const unsigned kControlMsgSize = CMSG_SPACE(sizeof(int)); - - struct kernel_msghdr msg; - my_memset(&msg, 0, sizeof(struct kernel_msghdr)); - struct kernel_iovec iov[1]; - iov[0].iov_base = const_cast(blob); - iov[0].iov_len = blob_size; - - msg.msg_iov = iov; - msg.msg_iovlen = sizeof(iov) / sizeof(iov[0]); - char cmsg[kControlMsgSize]; - my_memset(cmsg, 0, kControlMsgSize); - msg.msg_control = cmsg; - msg.msg_controllen = sizeof(cmsg); - - struct cmsghdr* hdr = CMSG_FIRSTHDR(&msg); - hdr->cmsg_level = SOL_SOCKET; - hdr->cmsg_type = SCM_RIGHTS; - hdr->cmsg_len = CMSG_LEN(sizeof(int)); - int* p = reinterpret_cast(CMSG_DATA(hdr)); - *p = fds[1]; - - ssize_t ret = HANDLE_EINTR(sys_sendmsg(server_fd_, &msg, 0)); - sys_close(fds[1]); - if (ret <= 0) - return false; - - // wait for an ACK from the server - char b; - IGNORE_RET(HANDLE_EINTR(sys_read(fds[0], &b, 1))); - - return true; -} +namespace { + +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]; + if (sys_socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) + return false; + static const unsigned kControlMsgSize = CMSG_SPACE(sizeof(int)); + + struct kernel_iovec iov; + iov.iov_base = const_cast(blob); + iov.iov_len = blob_size; + + struct kernel_msghdr msg = { 0 }; + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + char cmsg[kControlMsgSize] = ""; + msg.msg_control = cmsg; + msg.msg_controllen = sizeof(cmsg); -//static -CrashGenerationClient* -CrashGenerationClient::TryCreate(int server_fd) -{ - if (0 > server_fd) + struct cmsghdr* hdr = CMSG_FIRSTHDR(&msg); + hdr->cmsg_level = SOL_SOCKET; + hdr->cmsg_type = SCM_RIGHTS; + hdr->cmsg_len = CMSG_LEN(sizeof(int)); + int* p = reinterpret_cast(CMSG_DATA(hdr)); + *p = fds[1]; + + ssize_t ret = HANDLE_EINTR(sys_sendmsg(server_fd_, &msg, 0)); + sys_close(fds[1]); + if (ret < 0) + return false; + + // Wait for an ACK from the server. + char b; + IGNORE_RET(HANDLE_EINTR(sys_read(fds[0], &b, 1))); + sys_close(fds[0]); + + return true; + } + + private: + int server_fd_; + + DISALLOW_COPY_AND_ASSIGN(CrashGenerationClientImpl); +}; + +} // namespace + +// static +CrashGenerationClient* CrashGenerationClient::TryCreate(int server_fd) { + if (server_fd < 0) return NULL; - return new CrashGenerationClient(server_fd); + return new CrashGenerationClientImpl(server_fd); } -} +} // namespace google_breakpad -- cgit v1.2.1