Skip to content

Commit

Permalink
enums: Symbolize in maps
Browse files Browse the repository at this point in the history
This commit teaches bpftrace to symbolize enums when used in mapsfor the
default human-readable output. We leave JSON output alone for now in
case machines are parsing the current output format.

This should make it easier to aggregate by enums without having to go
thru the extra step of consulting enum definitions.
  • Loading branch information
danobi committed Oct 29, 2024
1 parent 96497cf commit 9ac33c7
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 27 deletions.
12 changes: 12 additions & 0 deletions .github/include/aot_skip.txt
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,20 @@ aot.json-output.scalar
aot.json-output.scalar_str
aot.json-output.stats
aot.other.if_compare_and_print_string
# Enum metadata is not being serialized
aot.other.no symbolize enum after arithmetic
# Enum metadata is not being serialized
aot.other.no symbolize enum after arithmetic mixed
aot.other.per_cpu_map_arithmetic
aot.other.per_cpu_map_avg_if
# Enum metadata is not being serialized
aot.other.symbolize enum in map key
# Enum metadata is not being serialized
aot.other.symbolize enum in map value
# Enum metadata is not being serialized
aot.other.symbolize enum in tuple map key
# Enum metadata is not being serialized
aot.other.symbolize enum in tuple map value
aot.probe.fentry
aot.probe.fentry args
aot.probe.fentry args as a pointer
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ and this project adheres to
- [#3300](https://github.com/bpftrace/bpftrace/pull/3300)
- Change `delete` API to accept a map and key as separate args
- [#3472](https://github.com/bpftrace/bpftrace/pull/3472)
- Symbolize enums when used in maps
- [#3539](https://github.com/bpftrace/bpftrace/pull/3539)
#### Deprecated
#### Removed
- Remove the `-dd` CLI option
Expand Down
89 changes: 62 additions & 27 deletions src/output.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -341,33 +341,68 @@ std::string Output::value_to_str(BPFtrace &bpftrace,
return std::to_string(read_data<uint64_t>(value.data()) / div);
}
case Type::integer: {
auto sign = type.IsSigned();
switch (type.GetIntBitWidth()) {
// clang-format off
case 64:
if (sign)
return std::to_string(reduce_value<int64_t>(value, nvalues) / static_cast<int64_t>(div));
return std::to_string(reduce_value<uint64_t>(value, nvalues) / div);
case 32:
if (sign)
return std::to_string(
reduce_value<int32_t>(value, nvalues) / static_cast<int32_t>(div));
return std::to_string(reduce_value<uint32_t>(value, nvalues) / div);
case 16:
if (sign)
return std::to_string(
reduce_value<int16_t>(value, nvalues) / static_cast<int16_t>(div));
return std::to_string(reduce_value<uint16_t>(value, nvalues) / div);
case 8:
if (sign)
return std::to_string(
reduce_value<int8_t>(value, nvalues) / static_cast<int8_t>(div));
return std::to_string(reduce_value<uint8_t>(value, nvalues) / div);
// clang-format on
default:
LOG(BUG) << "value_to_str: Invalid int bitwidth: "
<< type.GetIntBitWidth() << "provided";
return {};
if (type.IsEnumTy() && div == 1) {
assert(!is_per_cpu);

auto data = value.data();
auto enum_name = type.GetName();
uint64_t enum_val;
switch (type.GetIntBitWidth()) {
case 64:
enum_val = read_data<uint64_t>(data);
break;
case 32:
enum_val = read_data<uint32_t>(data);
break;
case 16:
enum_val = read_data<uint16_t>(data);
break;
case 8:
enum_val = read_data<uint8_t>(data);
break;
default:
LOG(BUG) << "value_to_str: Invalid int bitwidth: "
<< type.GetIntBitWidth() << "provided";
return {};
}

if (bpftrace.enum_defs_.contains(enum_name) &&
bpftrace.enum_defs_[enum_name].contains(enum_val)) {
return bpftrace.enum_defs_[enum_name][enum_val];
} else {
// Fall back to something comprehensible in case user somehow
// tricked the type system into accepting an invalid enum.
return std::to_string(enum_val);
}
} else {
auto sign = type.IsSigned();
switch (type.GetIntBitWidth()) {
// clang-format off
case 64:
if (sign)
return std::to_string(reduce_value<int64_t>(value, nvalues) / static_cast<int64_t>(div));
return std::to_string(reduce_value<uint64_t>(value, nvalues) / div);
case 32:
if (sign)
return std::to_string(
reduce_value<int32_t>(value, nvalues) / static_cast<int32_t>(div));
return std::to_string(reduce_value<uint32_t>(value, nvalues) / div);
case 16:
if (sign)
return std::to_string(
reduce_value<int16_t>(value, nvalues) / static_cast<int16_t>(div));
return std::to_string(reduce_value<uint16_t>(value, nvalues) / div);
case 8:
if (sign)
return std::to_string(
reduce_value<int8_t>(value, nvalues) / static_cast<int8_t>(div));
return std::to_string(reduce_value<uint8_t>(value, nvalues) / div);
// clang-format on
default:
LOG(BUG) << "value_to_str: Invalid int bitwidth: "
<< type.GetIntBitWidth() << "provided";
return {};
}
}
}
case Type::sum_t: {
Expand Down
27 changes: 27 additions & 0 deletions tests/runtime/other
Original file line number Diff line number Diff line change
Expand Up @@ -279,3 +279,30 @@ NAME dry run empty output
RUN {{BPFTRACE}} --dry-run -e 'BEGIN { printf("hello\n"); @ = 0; }'
EXPECT_NONE hello
EXPECT_NONE @: 0

NAME symbolize enum in map key
PROG enum { ONE = 1, TWO = 2 }; BEGIN { @[ONE] = 11; @[TWO] = 22; @m[ONE] = 333; exit(); }
EXPECT @[ONE]: 11
EXPECT @[TWO]: 22
EXPECT @m[ONE]: 333

NAME symbolize enum in tuple map key
PROG enum { ONE = 1, TWO = 2 }; BEGIN { @[ONE,TWO,ONE] = -1; exit(); }
EXPECT @[ONE, TWO, ONE]: -1

NAME symbolize enum in map value
PROG enum { ONE = 1, TWO = 2 }; BEGIN { @ = ONE; exit(); }
EXPECT @: ONE

NAME symbolize enum in tuple map value
PROG enum { ONE = 1, TWO = 2 }; BEGIN { @ = (ONE, TWO); exit(); }
EXPECT @: (ONE, TWO)

NAME no symbolize enum after arithmetic
PROG enum { ONE = 1, TWO = 2 }; BEGIN { @[ONE+1] = TWO-1; exit(); }
EXPECT @[2]: 1

NAME no symbolize enum after arithmetic mixed
PROG enum { ONE = 1, TWO = 2 }; BEGIN { @[ONE+1] = TWO-1; @[ONE] = ONE; exit(); }
EXPECT @[2]: 1
EXPECT @[1]: 1

0 comments on commit 9ac33c7

Please sign in to comment.