Propagate all sanitizer flags in SDK snapshots.
liblog snapshot needs to sanitizer.address=false to avoid cycle in asan builds. Adding that separately in library_sdk_member.go would start to feel like whack-a-mole, so the snapshot generation is instead extended to handle nested property structs. This uses the BpPropertySet.AddProperty extension in https://r.android.com/1423510, and common value optimisation now recurses into non-anonymous structs, instead of comparing them as a whole. Test: m nothing Test: `m SANITIZE_TARGET=address nothing` with prebuilts/runtime present in the manifest and a fresh snapshot made with this Bug: 151303681 Change-Id: I472554117a488e6c800045cb2ed59377778571a4
This commit is contained in:
@@ -1348,7 +1348,8 @@ type isHostVariant interface {
|
||||
|
||||
// A property that can be optimized by the commonValueExtractor.
|
||||
type extractorProperty struct {
|
||||
// The name of the field for this property.
|
||||
// The name of the field for this property. It is a "."-separated path for
|
||||
// fields in non-anonymous substructs.
|
||||
name string
|
||||
|
||||
// Filter that can use metadata associated with the properties being optimized
|
||||
@@ -1385,18 +1386,18 @@ type commonValueExtractor struct {
|
||||
func newCommonValueExtractor(propertiesStruct interface{}) *commonValueExtractor {
|
||||
structType := getStructValue(reflect.ValueOf(propertiesStruct)).Type()
|
||||
extractor := &commonValueExtractor{}
|
||||
extractor.gatherFields(structType, nil)
|
||||
extractor.gatherFields(structType, nil, "")
|
||||
return extractor
|
||||
}
|
||||
|
||||
// Gather the fields from the supplied structure type from which common values will
|
||||
// be extracted.
|
||||
//
|
||||
// This is recursive function. If it encounters an embedded field (no field name)
|
||||
// that is a struct then it will recurse into that struct passing in the accessor
|
||||
// for the field. That will then be used in the accessors for the fields in the
|
||||
// embedded struct.
|
||||
func (e *commonValueExtractor) gatherFields(structType reflect.Type, containingStructAccessor fieldAccessorFunc) {
|
||||
// This is recursive function. If it encounters a struct then it will recurse
|
||||
// into it, passing in the accessor for the field and the struct name as prefix
|
||||
// for the nested fields. That will then be used in the accessors for the fields
|
||||
// in the embedded struct.
|
||||
func (e *commonValueExtractor) gatherFields(structType reflect.Type, containingStructAccessor fieldAccessorFunc, namePrefix string) {
|
||||
for f := 0; f < structType.NumField(); f++ {
|
||||
field := structType.Field(f)
|
||||
if field.PkgPath != "" {
|
||||
@@ -1426,7 +1427,7 @@ func (e *commonValueExtractor) gatherFields(structType reflect.Type, containingS
|
||||
// Save a copy of the field index for use in the function.
|
||||
fieldIndex := f
|
||||
|
||||
name := field.Name
|
||||
name := namePrefix + field.Name
|
||||
|
||||
fieldGetter := func(value reflect.Value) reflect.Value {
|
||||
if containingStructAccessor != nil {
|
||||
@@ -1448,9 +1449,15 @@ func (e *commonValueExtractor) gatherFields(structType reflect.Type, containingS
|
||||
return value.Field(fieldIndex)
|
||||
}
|
||||
|
||||
if field.Type.Kind() == reflect.Struct && field.Anonymous {
|
||||
// Gather fields from the embedded structure.
|
||||
e.gatherFields(field.Type, fieldGetter)
|
||||
if field.Type.Kind() == reflect.Struct {
|
||||
// Gather fields from the nested or embedded structure.
|
||||
var subNamePrefix string
|
||||
if field.Anonymous {
|
||||
subNamePrefix = namePrefix
|
||||
} else {
|
||||
subNamePrefix = name + "."
|
||||
}
|
||||
e.gatherFields(field.Type, fieldGetter, subNamePrefix)
|
||||
} else {
|
||||
property := extractorProperty{
|
||||
name,
|
||||
@@ -1514,7 +1521,8 @@ func (c dynamicMemberPropertiesContainer) String() string {
|
||||
// Iterates over each exported field (capitalized name) and checks to see whether they
|
||||
// have the same value (using DeepEquals) across all the input properties. If it does not then no
|
||||
// change is made. Otherwise, the common value is stored in the field in the commonProperties
|
||||
// and the field in each of the input properties structure is set to its default value.
|
||||
// and the field in each of the input properties structure is set to its default value. Nested
|
||||
// structs are visited recursively and their non-struct fields are compared.
|
||||
func (e *commonValueExtractor) extractCommonProperties(commonProperties interface{}, inputPropertiesSlice interface{}) error {
|
||||
commonPropertiesValue := reflect.ValueOf(commonProperties)
|
||||
commonStructValue := commonPropertiesValue.Elem()
|
||||
|
Reference in New Issue
Block a user