Add functions to interact with ASan and MSan, and some sample uses
The sample uses are from when I debugged bug 617124. The change in neteq_network_stats_unittest.cc is a fix for a minor unrelated bug found by the try bots when I tried to land this CL (a test was passing uninitialized packet data to NetEq). BUG=chromium:617124 Review-Url: https://codereview.webrtc.org/2293893002 Cr-Commit-Position: refs/heads/master@{#14034}
This commit is contained in:
@ -152,6 +152,7 @@ static_library("rtc_base_approved") {
|
||||
"refcount.h",
|
||||
"safe_conversions.h",
|
||||
"safe_conversions_impl.h",
|
||||
"sanitizer.h",
|
||||
"scoped_ref_ptr.h",
|
||||
"stringencode.cc",
|
||||
"stringencode.h",
|
||||
|
||||
@ -130,6 +130,11 @@ class ArrayView final {
|
||||
size_t size_;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
inline ArrayView<T> MakeArrayView(T* data, size_t size) {
|
||||
return ArrayView<T>(data, size);
|
||||
}
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif // WEBRTC_BASE_ARRAY_VIEW_H_
|
||||
|
||||
@ -82,6 +82,7 @@
|
||||
'refcount.h',
|
||||
'safe_conversions.h',
|
||||
'safe_conversions_impl.h',
|
||||
'sanitizer.h',
|
||||
'scoped_ref_ptr.h',
|
||||
'stringencode.cc',
|
||||
'stringencode.h',
|
||||
|
||||
107
webrtc/base/sanitizer.h
Normal file
107
webrtc/base/sanitizer.h
Normal file
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright 2016 The WebRTC Project Authors. All rights reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_BASE_SANITIZER_H_
|
||||
#define WEBRTC_BASE_SANITIZER_H_
|
||||
|
||||
#if defined(__has_feature)
|
||||
#if __has_feature(address_sanitizer)
|
||||
#define RTC_HAS_ASAN 1
|
||||
#endif
|
||||
#if __has_feature(memory_sanitizer)
|
||||
#define RTC_HAS_MSAN 1
|
||||
#endif
|
||||
#endif
|
||||
#ifndef RTC_HAS_ASAN
|
||||
#define RTC_HAS_ASAN 0
|
||||
#endif
|
||||
#ifndef RTC_HAS_MSAN
|
||||
#define RTC_HAS_MSAN 0
|
||||
#endif
|
||||
|
||||
#if RTC_HAS_ASAN
|
||||
#include <sanitizer/asan_interface.h>
|
||||
#endif
|
||||
#if RTC_HAS_MSAN
|
||||
#include <sanitizer/msan_interface.h>
|
||||
#endif
|
||||
|
||||
// Ask ASan to mark the memory range [ptr, ptr + element_size * num_elements)
|
||||
// as being unaddressable, so that reads and writes are not allowed. ASan may
|
||||
// narrow the range to the nearest alignment boundaries.
|
||||
static inline void rtc_AsanPoison(const volatile void* ptr,
|
||||
size_t element_size,
|
||||
size_t num_elements) {
|
||||
#if RTC_HAS_ASAN
|
||||
ASAN_POISON_MEMORY_REGION(ptr, element_size * num_elements);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Ask ASan to mark the memory range [ptr, ptr + element_size * num_elements)
|
||||
// as being addressable, so that reads and writes are allowed. ASan may widen
|
||||
// the range to the nearest alignment boundaries.
|
||||
static inline void rtc_AsanUnpoison(const volatile void* ptr,
|
||||
size_t element_size,
|
||||
size_t num_elements) {
|
||||
#if RTC_HAS_ASAN
|
||||
ASAN_UNPOISON_MEMORY_REGION(ptr, element_size * num_elements);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Ask MSan to mark the memory range [ptr, ptr + element_size * num_elements)
|
||||
// as being uninitialized.
|
||||
static inline void rtc_MsanMarkUninitialized(const volatile void* ptr,
|
||||
size_t element_size,
|
||||
size_t num_elements) {
|
||||
#if RTC_HAS_MSAN
|
||||
__msan_poison(ptr, element_size * num_elements);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Force an MSan check (if any bits in the memory range [ptr, ptr +
|
||||
// element_size * num_elements) are uninitialized the call will crash with an
|
||||
// MSan report).
|
||||
static inline void rtc_MsanCheckInitialized(const volatile void* ptr,
|
||||
size_t element_size,
|
||||
size_t num_elements) {
|
||||
#if RTC_HAS_MSAN
|
||||
__msan_check_mem_is_initialized(ptr, element_size * num_elements);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
namespace rtc {
|
||||
|
||||
template <typename T>
|
||||
inline void AsanPoison(const T& mem) {
|
||||
rtc_AsanPoison(mem.data(), sizeof(mem.data()[0]), mem.size());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void AsanUnpoison(const T& mem) {
|
||||
rtc_AsanUnpoison(mem.data(), sizeof(mem.data()[0]), mem.size());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void MsanMarkUninitialized(const T& mem) {
|
||||
rtc_MsanMarkUninitialized(mem.data(), sizeof(mem.data()[0]), mem.size());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void MsanCheckInitialized(const T& mem) {
|
||||
rtc_MsanCheckInitialized(mem.data(), sizeof(mem.data()[0]), mem.size());
|
||||
}
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // WEBRTC_BASE_SANITIZER_H_
|
||||
@ -10,6 +10,9 @@
|
||||
|
||||
#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
|
||||
|
||||
#include "webrtc/base/checks.h"
|
||||
#include "webrtc/base/sanitizer.h"
|
||||
|
||||
// TODO(Bjornv): Change the function parameter order to WebRTC code style.
|
||||
// C version of WebRtcSpl_DownsampleFast() for generic platforms.
|
||||
int WebRtcSpl_DownsampleFastC(const int16_t* data_in,
|
||||
@ -20,6 +23,7 @@ int WebRtcSpl_DownsampleFastC(const int16_t* data_in,
|
||||
size_t coefficients_length,
|
||||
int factor,
|
||||
size_t delay) {
|
||||
int16_t* const original_data_out = data_out;
|
||||
size_t i = 0;
|
||||
size_t j = 0;
|
||||
int32_t out_s32 = 0;
|
||||
@ -31,10 +35,14 @@ int WebRtcSpl_DownsampleFastC(const int16_t* data_in,
|
||||
return -1;
|
||||
}
|
||||
|
||||
rtc_MsanCheckInitialized(coefficients, sizeof(coefficients[0]),
|
||||
coefficients_length);
|
||||
|
||||
for (i = delay; i < endpos; i += factor) {
|
||||
out_s32 = 2048; // Round value, 0.5 in Q12.
|
||||
|
||||
for (j = 0; j < coefficients_length; j++) {
|
||||
rtc_MsanCheckInitialized(&data_in[i - j], sizeof(data_in[0]), 1);
|
||||
out_s32 += coefficients[j] * data_in[i - j]; // Q12.
|
||||
}
|
||||
|
||||
@ -44,5 +52,9 @@ int WebRtcSpl_DownsampleFastC(const int16_t* data_in,
|
||||
*data_out++ = WebRtcSpl_SatW32ToW16(out_s32);
|
||||
}
|
||||
|
||||
RTC_DCHECK_EQ(original_data_out + data_out_length, data_out);
|
||||
rtc_MsanCheckInitialized(original_data_out, sizeof(original_data_out[0]),
|
||||
data_out_length);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -17,6 +17,8 @@
|
||||
|
||||
#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
|
||||
|
||||
#include "webrtc/base/sanitizer.h"
|
||||
|
||||
void WebRtcSpl_FilterMAFastQ12(const int16_t* in_ptr,
|
||||
int16_t* out_ptr,
|
||||
const int16_t* B,
|
||||
@ -24,6 +26,11 @@ void WebRtcSpl_FilterMAFastQ12(const int16_t* in_ptr,
|
||||
size_t length)
|
||||
{
|
||||
size_t i, j;
|
||||
|
||||
rtc_MsanCheckInitialized(B, sizeof(B[0]), B_length);
|
||||
rtc_MsanCheckInitialized(in_ptr - B_length + 1, sizeof(in_ptr[0]),
|
||||
B_length + length - 1);
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
int32_t o = 0;
|
||||
|
||||
@ -12,7 +12,9 @@
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "webrtc/base/array_view.h"
|
||||
#include "webrtc/base/checks.h"
|
||||
#include "webrtc/base/sanitizer.h"
|
||||
#include "webrtc/base/trace_event.h"
|
||||
|
||||
namespace webrtc {
|
||||
@ -21,6 +23,7 @@ int AudioDecoder::Decode(const uint8_t* encoded, size_t encoded_len,
|
||||
int sample_rate_hz, size_t max_decoded_bytes,
|
||||
int16_t* decoded, SpeechType* speech_type) {
|
||||
TRACE_EVENT0("webrtc", "AudioDecoder::Decode");
|
||||
rtc::MsanCheckInitialized(rtc::MakeArrayView(encoded, encoded_len));
|
||||
int duration = PacketDuration(encoded, encoded_len);
|
||||
if (duration >= 0 &&
|
||||
duration * Channels() * sizeof(int16_t) > max_decoded_bytes) {
|
||||
@ -34,6 +37,7 @@ int AudioDecoder::DecodeRedundant(const uint8_t* encoded, size_t encoded_len,
|
||||
int sample_rate_hz, size_t max_decoded_bytes,
|
||||
int16_t* decoded, SpeechType* speech_type) {
|
||||
TRACE_EVENT0("webrtc", "AudioDecoder::DecodeRedundant");
|
||||
rtc::MsanCheckInitialized(rtc::MakeArrayView(encoded, encoded_len));
|
||||
int duration = PacketDurationRedundant(encoded, encoded_len);
|
||||
if (duration >= 0 &&
|
||||
duration * Channels() * sizeof(int16_t) > max_decoded_bytes) {
|
||||
|
||||
@ -18,6 +18,7 @@
|
||||
|
||||
#include "defines.h"
|
||||
#include "constants.h"
|
||||
#include "webrtc/base/sanitizer.h"
|
||||
#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
|
||||
|
||||
/*----------------------------------------------------------------*
|
||||
@ -40,6 +41,9 @@ void WebRtcIlbcfix_CreateAugmentedVec(
|
||||
*/
|
||||
size_t interp_len = WEBRTC_SPL_MIN(index, 4);
|
||||
|
||||
rtc_MsanCheckInitialized(buffer - index - interp_len, sizeof(buffer[0]),
|
||||
index + interp_len);
|
||||
|
||||
ilow = index - interp_len;
|
||||
|
||||
/* copy the first noninterpolated part */
|
||||
|
||||
@ -19,6 +19,7 @@
|
||||
#include "webrtc/base/checks.h"
|
||||
#include "webrtc/base/logging.h"
|
||||
#include "webrtc/base/safe_conversions.h"
|
||||
#include "webrtc/base/sanitizer.h"
|
||||
#include "webrtc/base/trace_event.h"
|
||||
#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
|
||||
#include "webrtc/modules/audio_coding/codecs/audio_decoder.h"
|
||||
@ -132,6 +133,7 @@ NetEqImpl::~NetEqImpl() = default;
|
||||
int NetEqImpl::InsertPacket(const WebRtcRTPHeader& rtp_header,
|
||||
rtc::ArrayView<const uint8_t> payload,
|
||||
uint32_t receive_timestamp) {
|
||||
rtc::MsanCheckInitialized(payload);
|
||||
TRACE_EVENT0("webrtc", "NetEqImpl::InsertPacket");
|
||||
rtc::CritScope lock(&crit_sect_);
|
||||
int error =
|
||||
|
||||
@ -201,7 +201,8 @@ NetEqNetworkStatsTest(NetEqDecoder codec,
|
||||
frame_size_samples_,
|
||||
&rtp_header_);
|
||||
if (!Lost(next_send_time)) {
|
||||
InsertPacket(rtp_header_, payload_, next_send_time);
|
||||
static const uint8_t payload[kPayloadSizeByte] = {0};
|
||||
InsertPacket(rtp_header_, payload, next_send_time);
|
||||
}
|
||||
}
|
||||
GetOutputAudio(&output_frame_);
|
||||
@ -277,7 +278,6 @@ NetEqNetworkStatsTest(NetEqDecoder codec,
|
||||
WebRtcRTPHeader rtp_header_;
|
||||
uint32_t last_lost_time_;
|
||||
uint32_t packet_loss_interval_;
|
||||
uint8_t payload_[kPayloadSizeByte];
|
||||
AudioFrame output_frame_;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user