Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Android/bionic/bionic/tests/   (Android Betriebssystem Version 17©)  Datei vom 26.5.2026 mit Größe 10 kB image not shown  

Quelle  gwp_asan_test.cpp

  Sprache: C
 

/*
 * Copyright (C) 2021 The Android Open Source Project
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (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 <gtest/gtest.h>
#include <stdio.h>
#include <sys/file.h>
#include <string>

#if defined(__BIONIC__)

#include "android-base/file.h"
#include "android-base/silent_death_test.h"
#include "android-base/test_utils.h"
#include "gwp_asan/options.h"
#include "platform/bionic/malloc.h"
#include "sys/system_properties.h"
#include "utils.h"

using gwp_asan_integration_DeathTest = SilentDeathTest;

// basename is a mess, use gnu basename explicitly to avoid the need for string
// mutation.
extern "C" const char* __gnu_basename(const char* path);

// GWP-ASan tests can run much slower, especially when combined with HWASan.
// Triple the deadline to avoid flakes (b/238585984).
extern "C" bool GetInitialArgs(const char*** args, size_t* num_args) {
  static const char* initial_args[] = {"--deadline_threshold_ms=270000"};
  *args = initial_args;
  *num_args = 1;
  return true;
}

// This file implements "torture testing" under GWP-ASan, where we sample every
// single allocation. The upper limit for the number of GWP-ASan allocations in
// the torture mode is is generally 40,000, so that svelte devices don't
// explode, as this uses ~163MiB RAM (4KiB per live allocation).
TEST(gwp_asan_integration, malloc_tests_under_torture) {
  // Do not override HWASan with GWP ASan.
  SKIP_WITH_HWASAN;

  RunGwpAsanTest("malloc.*:-malloc.mallinfo*");
}

class SyspropRestorer {
 private:
  std::vector<std::pair<std::string, std::string>> props_to_restore_;
  // System properties are global for a device, so the tests that mutate the
  // GWP-ASan system properties must be run mutually exclusive. Because
  // bionic-unit-tests is run in an isolated gtest fashion (each test is run in
  // its own process), we have to use flocks to synchronise between tests.
  int flock_fd_;

 public:
  SyspropRestorer() {
    std::string path = testing::internal::GetArgvs()[0];
    flock_fd_ = open(path.c_str(), O_RDONLY);
    EXPECT_NE(flock_fd_, -1) << "failed to open self for a flock";
    EXPECT_NE(flock(flock_fd_, LOCK_EX), -1) << "failed to flock myself";

    const char* basename = __gnu_basename(path.c_str());
    std::vector<std::string> props = {
        std::string("libc.debug.gwp_asan.sample_rate.") + basename,
        std::string("libc.debug.gwp_asan.process_sampling.") + basename,
        std::string("libc.debug.gwp_asan.max_allocs.") + basename,
        "libc.debug.gwp_asan.sample_rate.system_default",
        "libc.debug.gwp_asan.sample_rate.app_default",
        "libc.debug.gwp_asan.process_sampling.system_default",
        "libc.debug.gwp_asan.process_sampling.app_default",
        "libc.debug.gwp_asan.max_allocs.system_default",
        "libc.debug.gwp_asan.max_allocs.app_default",
    };

    size_t base_props_size = props.size();
    for (size_t i = 0; i < base_props_size; ++i) {
      props.push_back("persist." + props[i]);
    }

    std::string reset_log;

    for (const std::string& prop : props) {
      std::string value = GetSysprop(prop);
      props_to_restore_.emplace_back(prop, value);
      if (!value.empty()) {
        __system_property_set(prop.c_str(), "");
      }
    }
  }

  ~SyspropRestorer() {
    for (const auto& kv : props_to_restore_) {
      if (kv.second != GetSysprop(kv.first)) {
        __system_property_set(kv.first.c_str(), kv.second.c_str());
      }
    }
    close(flock_fd_);
  }

  static std::string GetSysprop(const std::string& name) {
    std::string value;
    const prop_info* pi = __system_property_find(name.c_str());
    if (pi == nullptr) return value;
    __system_property_read_callback(
        pi,
        [](void* cookie, const char/* name */, const char* value, uint32_t /* serial */) {
          std::string* v = static_cast<std::string*>(cookie);
          *v = value;
        },
        &value);
    return value;
  }
};

TEST_F(gwp_asan_integration_DeathTest, DISABLED_assert_gwp_asan_enabled) {
  std::string maps;
  EXPECT_TRUE(android::base::ReadFileToString("/proc/self/maps", &maps));
  EXPECT_TRUE(maps.find("GWP-ASan") != std::string::npos) << maps;

  volatile int* x = new int;
  delete x;
  EXPECT_DEATH({ *x = 7; }, "");
}

// A weaker version of the above tests, only checking that GWP-ASan is enabled
// for any pointer, not *our* pointer. This allows us to test the system_default
// sysprops without potentially OOM-ing other random processes:
// b/273904016#comment5
TEST(gwp_asan_integration, DISABLED_assert_gwp_asan_enabled_weaker) {
  std::string maps;
  EXPECT_TRUE(android::base::ReadFileToString("/proc/self/maps", &maps));
  EXPECT_TRUE(maps.find("GWP-ASan") != std::string::npos) << maps;
}

TEST(gwp_asan_integration, DISABLED_assert_gwp_asan_disabled) {
  std::string maps;
  EXPECT_TRUE(android::base::ReadFileToString("/proc/self/maps", &maps));
  EXPECT_TRUE(maps.find("GWP-ASan") == std::string::npos);
}

TEST(gwp_asan_integration, sysprops_program_specific) {
  // Do not override HWASan with GWP ASan.
  SKIP_WITH_HWASAN;

  SyspropRestorer restorer;

  std::string path = testing::internal::GetArgvs()[0];
  const char* basename = __gnu_basename(path.c_str());
  __system_property_set((std::string("libc.debug.gwp_asan.sample_rate.") + basename).c_str(), "1");
  __system_property_set((std::string("libc.debug.gwp_asan.process_sampling.") + basename).c_str(),
                        "1");
  __system_property_set((std::string("libc.debug.gwp_asan.max_allocs.") + basename).c_str(),
                        "40000");

  RunSubtestNoEnv("gwp_asan_integration_DeathTest.DISABLED_assert_gwp_asan_enabled");
}

TEST(gwp_asan_integration, sysprops_persist_program_specific) {
  // Do not override HWASan with GWP ASan.
  SKIP_WITH_HWASAN;

  SyspropRestorer restorer;

  std::string path = testing::internal::GetArgvs()[0];
  const char* basename = __gnu_basename(path.c_str());
  __system_property_set(
      (std::string("persist.libc.debug.gwp_asan.sample_rate.") + basename).c_str(), "1");
  __system_property_set(
      (std::string("persist.libc.debug.gwp_asan.process_sampling.") + basename).c_str(), "1");
  __system_property_set((std::string("persist.libc.debug.gwp_asan.max_allocs.") + basename).c_str(),
                        "40000");

  RunSubtestNoEnv("gwp_asan_integration_DeathTest.DISABLED_assert_gwp_asan_enabled");
}

TEST(gwp_asan_integration, sysprops_non_persist_overrides_persist) {
  // Do not override HWASan with GWP ASan.
  SKIP_WITH_HWASAN;

  SyspropRestorer restorer;

  __system_property_set("libc.debug.gwp_asan.sample_rate.system_default""1");
  __system_property_set("libc.debug.gwp_asan.process_sampling.system_default""1");
  // Note, any processes launched elsewhere on the system right now will have
  // GWP-ASan enabled. Make sure that we only use a single slot, otherwise we
  // could end up causing said badly-timed processes to use up to 163MiB extra
  // penalty that 40,000 allocs would cause. See b/273904016#comment5 for more
  // context.
  __system_property_set("libc.debug.gwp_asan.max_allocs.system_default""1");

  __system_property_set("persist.libc.debug.gwp_asan.sample_rate.system_default""0");
  __system_property_set("persist.libc.debug.gwp_asan.process_sampling.system_default""0");
  __system_property_set("persist.libc.debug.gwp_asan.max_allocs.system_default""0");

  RunSubtestNoEnv("gwp_asan_integration.DISABLED_assert_gwp_asan_enabled_weaker");
}

TEST(gwp_asan_integration, sysprops_program_specific_overrides_default) {
  // Do not override HWASan with GWP ASan.
  SKIP_WITH_HWASAN;

  SyspropRestorer restorer;

  std::string path = testing::internal::GetArgvs()[0];
  const char* basename = __gnu_basename(path.c_str());
  __system_property_set(
      (std::string("persist.libc.debug.gwp_asan.sample_rate.") + basename).c_str(), "1");
  __system_property_set(
      (std::string("persist.libc.debug.gwp_asan.process_sampling.") + basename).c_str(), "1");
  __system_property_set((std::string("persist.libc.debug.gwp_asan.max_allocs.") + basename).c_str(),
                        "40000");

  __system_property_set("libc.debug.gwp_asan.sample_rate.system_default""0");
  __system_property_set("libc.debug.gwp_asan.process_sampling.system_default""0");
  __system_property_set("libc.debug.gwp_asan.max_allocs.system_default""0");

  RunSubtestNoEnv("gwp_asan_integration_DeathTest.DISABLED_assert_gwp_asan_enabled");
}

TEST(gwp_asan_integration, sysprops_can_disable) {
  // Do not override HWASan with GWP ASan.
  SKIP_WITH_HWASAN;

  SyspropRestorer restorer;

  __system_property_set("libc.debug.gwp_asan.sample_rate.system_default""0");
  __system_property_set("libc.debug.gwp_asan.process_sampling.system_default""0");
  __system_property_set("libc.debug.gwp_asan.max_allocs.system_default""0");

  RunSubtestNoEnv("gwp_asan_integration.DISABLED_assert_gwp_asan_disabled");
}

TEST(gwp_asan_integration, env_overrides_sysprop) {
  // Do not override HWASan with GWP ASan.
  SKIP_WITH_HWASAN;

  SyspropRestorer restorer;

  __system_property_set("libc.debug.gwp_asan.sample_rate.system_default""0");
  __system_property_set("libc.debug.gwp_asan.process_sampling.system_default""0");
  __system_property_set("libc.debug.gwp_asan.max_allocs.system_default""0");

  RunGwpAsanTest("gwp_asan_integration_DeathTest.DISABLED_assert_gwp_asan_enabled");
}

#endif  // defined(__BIONIC__)

Messung V0.5 in Prozent
C=80 H=98 G=89

¤ Dauer der Verarbeitung: 0.10 Sekunden  (vorverarbeitet am  2026-06-28) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.