From f8c8ae8bf435d845de07141231fa8c4e318cdf38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tonko=20Sabol=C4=8Dec?= Date: Fri, 18 Jun 2021 11:19:02 +0200 Subject: [PATCH 1/4] [fuzzer] Fix Linux specific issues --- testdata/fuzzer_binary.cc | 4 ++++ testdata/rules.bzl | 2 +- tools/fuzzer/expr_gen.cc | 31 +++++++++++++++++++++++++------ tools/fuzzer/expr_gen.h | 3 +++ 4 files changed, 33 insertions(+), 7 deletions(-) diff --git a/testdata/fuzzer_binary.cc b/testdata/fuzzer_binary.cc index 32143cbe..7b7d043a 100644 --- a/testdata/fuzzer_binary.cc +++ b/testdata/fuzzer_binary.cc @@ -14,6 +14,7 @@ * limitations under the License. */ +#include // size_t #include // This file _must not_ access the file system, since the current directory @@ -286,6 +287,9 @@ int main() { char** addr_null_char_ptr = &null_char_ptr; (void)null_char_ptr, (void)test_str, (void)addr_null_char_ptr; + size_t size_val = 5; + (void)size_val; + NonEmptyDerived empty_base; (void)empty_base; diff --git a/testdata/rules.bzl b/testdata/rules.bzl index 5b5f0be1..b94b7a74 100644 --- a/testdata/rules.bzl +++ b/testdata/rules.bzl @@ -38,7 +38,7 @@ def binary_gen(name, srcs): platform_opts = "--for-linker -debug:dwarf", ), "//conditions:default": build_cmd.format( - platform_opts = "-lstdc++", + platform_opts = "-lstdc++ -static", ), }), tags = ["no-sandbox"], diff --git a/tools/fuzzer/expr_gen.cc b/tools/fuzzer/expr_gen.cc index 721a1f42..b4bba252 100644 --- a/tools/fuzzer/expr_gen.cc +++ b/tools/fuzzer/expr_gen.cc @@ -200,6 +200,11 @@ std::optional ExprGenerator::gen_variable_expr_impl( std::vector> vars; for (const auto& [k, v] : symtab_.vars()) { + // Skip long double variables if long double isn't enabled. + if (!cfg_.long_double_enabled && k == Type(ScalarType::LongDouble)) { + continue; + } + if (type_constraints.allows_type(k)) { for (const auto& var : v) { if (var.expr.name() == "this" && constraints.must_be_lvalue()) { @@ -729,12 +734,21 @@ std::optional ExprGenerator::gen_member_of_ptr_expr_impl( Field field = rng_->pick_field(fields); TypeConstraints new_type_constraints(field.containing_type()); - // If the field is a reference or a virtually inherited field, assume a read - // from memory. - MemoryConstraints new_memory_constraints = - field.is_reference_or_virtual() - ? MemoryConstraints(true, 1) - : memory_constraints.from_member_of(constraints.must_be_lvalue(), 1); + + // `&(ptr)->field` is equivalent to `ptr + offset(field)` where offset can + // be determined statically if the `field` isn't a reference or a virtually + // inherited field (in these cases a read from memory is expected). However, + // lldb-eval doesn't support address-of elision for member-of expressions, + // so assume a read from memory in all cases. + MemoryConstraints new_memory_constraints(true, 1); + + // TODO: Uncomment the following code once lldb-eval supports address-of + // elision for member-of expressions. + // MemoryConstraints new_memory_constraints = + // field.is_reference_or_virtual() ? MemoryConstraints(true, 1) + // : memory_constraints.from_member_of( + // constraints.must_be_lvalue(), 1); + ExprConstraints new_constraints = ExprConstraints(new_type_constraints.make_pointer_constraints(), std::move(new_memory_constraints)); @@ -1267,6 +1281,11 @@ std::optional ExprGenerator::gen_tagged_type( std::optional ExprGenerator::gen_scalar_type( const TypeConstraints& constraints) { ScalarMask mask = constraints.allowed_scalar_types(); + + if (!cfg_.long_double_enabled) { + mask[ScalarType::LongDouble] = false; + } + if (mask.none()) { return {}; } diff --git a/tools/fuzzer/expr_gen.h b/tools/fuzzer/expr_gen.h index 2edd8f48..19355e2a 100644 --- a/tools/fuzzer/expr_gen.h +++ b/tools/fuzzer/expr_gen.h @@ -152,6 +152,9 @@ struct GenConfig { // from memory is expected. bool valid_pointer_cast_enabled = false; + // Long double may not work properly in lldb-eval yet. + bool long_double_enabled = false; + BinOpMask bin_op_mask = BinOpMask::all_set(); UnOpMask un_op_mask = UnOpMask::all_set(); From 10347ed2ce9a0ca2ad2aae0dc5bc497fa0a23e6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tonko=20Sabol=C4=8Dec?= Date: Fri, 18 Jun 2021 11:49:50 +0200 Subject: [PATCH 2/4] Fix symbol_table_test --- tools/fuzzer/symbol_table_test.cc | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/tools/fuzzer/symbol_table_test.cc b/tools/fuzzer/symbol_table_test.cc index 73f5db5c..0bc93c97 100644 --- a/tools/fuzzer/symbol_table_test.cc +++ b/tools/fuzzer/symbol_table_test.cc @@ -20,6 +20,7 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" +#include "lldb-eval/context.h" #include "lldb-eval/runner.h" #include "lldb-eval/traits.h" #include "lldb/API/SBDebugger.h" @@ -59,6 +60,7 @@ class PopulateSymbolTableTest : public Test { "// BREAK HERE"); auto frame = process_.GetSelectedThread().GetSelectedFrame(); symtab_ = SymbolTable::create_from_frame(frame); + context_ = lldb_eval::Context::Create(/*expr*/ "", frame); } static void TearDownTestSuite() { @@ -72,11 +74,13 @@ class PopulateSymbolTableTest : public Test { static Runfiles* runfiles_; static lldb::SBProcess process_; static SymbolTable symtab_; + static std::shared_ptr context_; }; Runfiles* PopulateSymbolTableTest::runfiles_ = nullptr; lldb::SBProcess PopulateSymbolTableTest::process_; SymbolTable PopulateSymbolTableTest::symtab_; +std::shared_ptr PopulateSymbolTableTest::context_; TEST_F(PopulateSymbolTableTest, Variables) { // Make sure there isn't a type we forgot to check. @@ -123,10 +127,19 @@ TEST_F(PopulateSymbolTableTest, Variables) { "global_int", "ns::global_int", "ns::nested_ns::global_int", "global_ref", "ns::global_ref", "StaticMember::s1", "ns::StaticMember::s1", "ClassWithNestedClass::NestedClass::s1"}); - expect_vars(ScalarType::UnsignedLong, {"ulong_min", "ulong_max"}); expect_vars(ScalarType::SignedLong, {"long_min", "long_max"}); - expect_vars(ScalarType::UnsignedLongLong, {"ullong_min", "ullong_max"}); expect_vars(ScalarType::SignedLongLong, {"llong_min", "llong_max"}); + + std::unordered_set ulong_vars{"ulong_min", "ulong_max"}; + std::unordered_set ullong_vars{"ullong_min", "ullong_max"}; + if (context_->GetSizeType().GetBasicType() == lldb::eBasicTypeUnsignedLong) { + ulong_vars.insert("size_val"); + } else { + ullong_vars.insert("size_val"); + } + expect_vars(ScalarType::UnsignedLong, ulong_vars); + expect_vars(ScalarType::UnsignedLongLong, ullong_vars); + expect_vars(ScalarType::Float, {"fnan", "finf", "fsnan", "fmax", "fdenorm"}); expect_vars(ScalarType::Double, {"dnan", "dinf", "dsnan", "dmax", "ddenorm"}); expect_vars(ScalarType::LongDouble, From 4d8e9c9022cfc3a60450eef1732e9e829e926498 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tonko=20Sabol=C4=8Dec?= Date: Fri, 18 Jun 2021 12:33:33 +0200 Subject: [PATCH 3/4] Add comment regarding -static --- testdata/rules.bzl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/testdata/rules.bzl b/testdata/rules.bzl index b94b7a74..14d8f5c9 100644 --- a/testdata/rules.bzl +++ b/testdata/rules.bzl @@ -38,6 +38,8 @@ def binary_gen(name, srcs): platform_opts = "--for-linker -debug:dwarf", ), "//conditions:default": build_cmd.format( + # Using "-static" prevents fuzzer_binary from using __log2 + # function from libm.so. platform_opts = "-lstdc++ -static", ), }), From 1a1a1fc73f6f7aebd16f7643e933fa1600bdfef5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tonko=20Sabol=C4=8Dec?= Date: Fri, 18 Jun 2021 12:55:58 +0200 Subject: [PATCH 4/4] Remove size_t from fuzzer_binary --- testdata/fuzzer_binary.cc | 4 ---- tools/fuzzer/symbol_table_test.cc | 17 ++--------------- 2 files changed, 2 insertions(+), 19 deletions(-) diff --git a/testdata/fuzzer_binary.cc b/testdata/fuzzer_binary.cc index 7b7d043a..32143cbe 100644 --- a/testdata/fuzzer_binary.cc +++ b/testdata/fuzzer_binary.cc @@ -14,7 +14,6 @@ * limitations under the License. */ -#include // size_t #include // This file _must not_ access the file system, since the current directory @@ -287,9 +286,6 @@ int main() { char** addr_null_char_ptr = &null_char_ptr; (void)null_char_ptr, (void)test_str, (void)addr_null_char_ptr; - size_t size_val = 5; - (void)size_val; - NonEmptyDerived empty_base; (void)empty_base; diff --git a/tools/fuzzer/symbol_table_test.cc b/tools/fuzzer/symbol_table_test.cc index 0bc93c97..73f5db5c 100644 --- a/tools/fuzzer/symbol_table_test.cc +++ b/tools/fuzzer/symbol_table_test.cc @@ -20,7 +20,6 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" -#include "lldb-eval/context.h" #include "lldb-eval/runner.h" #include "lldb-eval/traits.h" #include "lldb/API/SBDebugger.h" @@ -60,7 +59,6 @@ class PopulateSymbolTableTest : public Test { "// BREAK HERE"); auto frame = process_.GetSelectedThread().GetSelectedFrame(); symtab_ = SymbolTable::create_from_frame(frame); - context_ = lldb_eval::Context::Create(/*expr*/ "", frame); } static void TearDownTestSuite() { @@ -74,13 +72,11 @@ class PopulateSymbolTableTest : public Test { static Runfiles* runfiles_; static lldb::SBProcess process_; static SymbolTable symtab_; - static std::shared_ptr context_; }; Runfiles* PopulateSymbolTableTest::runfiles_ = nullptr; lldb::SBProcess PopulateSymbolTableTest::process_; SymbolTable PopulateSymbolTableTest::symtab_; -std::shared_ptr PopulateSymbolTableTest::context_; TEST_F(PopulateSymbolTableTest, Variables) { // Make sure there isn't a type we forgot to check. @@ -127,19 +123,10 @@ TEST_F(PopulateSymbolTableTest, Variables) { "global_int", "ns::global_int", "ns::nested_ns::global_int", "global_ref", "ns::global_ref", "StaticMember::s1", "ns::StaticMember::s1", "ClassWithNestedClass::NestedClass::s1"}); + expect_vars(ScalarType::UnsignedLong, {"ulong_min", "ulong_max"}); expect_vars(ScalarType::SignedLong, {"long_min", "long_max"}); + expect_vars(ScalarType::UnsignedLongLong, {"ullong_min", "ullong_max"}); expect_vars(ScalarType::SignedLongLong, {"llong_min", "llong_max"}); - - std::unordered_set ulong_vars{"ulong_min", "ulong_max"}; - std::unordered_set ullong_vars{"ullong_min", "ullong_max"}; - if (context_->GetSizeType().GetBasicType() == lldb::eBasicTypeUnsignedLong) { - ulong_vars.insert("size_val"); - } else { - ullong_vars.insert("size_val"); - } - expect_vars(ScalarType::UnsignedLong, ulong_vars); - expect_vars(ScalarType::UnsignedLongLong, ullong_vars); - expect_vars(ScalarType::Float, {"fnan", "finf", "fsnan", "fmax", "fdenorm"}); expect_vars(ScalarType::Double, {"dnan", "dinf", "dsnan", "dmax", "ddenorm"}); expect_vars(ScalarType::LongDouble,