crashpad/util/stream/log_output_stream.h
Joshua Peraza cdb1e7f52b fix flake in LogOutputStreamTest
LogOutputStreamTest.{WriteAbort,FlushAbort} are flaky because the logcat
is sometimes overloaded earlier than expected causing FlushAbort to fail
during Write() or either test to fail to write the abort message.

This change updates LogOutputStream to detect logcat overloads (EAGAIN)
and make one attempt at writing the abort message, even if the output
cap hasn't been reached.

This change also updates LogOutputStream's interface to defer log writes
to a Delegate. In tests, the Delegate implements a mock log and in
production, writes to Android's logcat.

I've removed VerifyGuards because LogOutputStream no longer writes
guards if Write() has never been called and the guards are tested in
other tests.

Change-Id: Icad83524aaf573c3e082469f1de095b6ca2c4839
Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/2439641
Reviewed-by: Mark Mentovai <mark@chromium.org>
2020-10-26 18:36:11 +00:00

78 lines
2.3 KiB
C++

// Copyright 2019 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_UTIL_STREAM_LOG_OUTPUT_STREAM_H_
#define CRASHPAD_UTIL_STREAM_LOG_OUTPUT_STREAM_H_
#include <stddef.h>
#include <stdint.h>
#include <memory>
#include <string>
#include "base/macros.h"
#include "util/stream/output_stream_interface.h"
namespace crashpad {
//! \brief This class outputs a stream of data as a series of log messages.
class LogOutputStream : public OutputStreamInterface {
public:
//! \brief An interface to a log output sink.
class Delegate {
public:
Delegate() = default;
virtual ~Delegate() = default;
//! \brief Logs |buf| to the output sink.
//!
//! \param buf the buffer to write to the log. More bytes than are in |buf|
//! may be written, e.g. to convey metadata.
//! \return the number of bytes written, or a negative error code.
virtual int Log(const char* buf) = 0;
//! \brief Returns the maximum number of bytes to allow writing to this log.
virtual size_t OutputCap() = 0;
//! \brief Returns the maximum length of buffers allowed to be passed to
//! Log().
virtual size_t LineWidth() = 0;
};
LogOutputStream(std::unique_ptr<Delegate> delegate);
~LogOutputStream() override;
// OutputStreamInterface:
bool Write(const uint8_t* data, size_t size) override;
bool Flush() override;
private:
// Flushes buffer_, returning false on failure.
bool WriteBuffer();
int WriteToLog(const char* buf);
std::string buffer_;
std::unique_ptr<Delegate> delegate_;
size_t output_count_;
bool flush_needed_;
bool flushed_;
DISALLOW_COPY_AND_ASSIGN(LogOutputStream);
};
} // namespace crashpad
#endif // CRASHPAD_UTIL_STREAM_LOG_OUTPUT_STREAM_H_