[IRMemoryMap] Use labels in the "malloc" and "free" lldb-test commands

Change the syntax of the malloc and free commands in lldb-test's
ir-memory-map subcommand to:

  <malloc> ::= <label> = malloc <size> <alignment>

  <free> ::= free <label>

This should make it easier to read and extend tests in the future, e.g
to test IRMemoryMap::WriteMemory or double-free behavior.

Differential Revision: https://reviews.llvm.org/D47646

llvm-svn: 333930
This commit is contained in:
Vedant Kumar 2018-06-04 17:11:15 +00:00
parent 675a51750a
commit c418b5cc25
4 changed files with 355 additions and 341 deletions

View File

@ -1,25 +1,25 @@
malloc 0 1 L1 = malloc 0 1
malloc 1 1 L2 = malloc 1 1
malloc 2 1 L3 = malloc 2 1
malloc 2 2 L4 = malloc 2 2
malloc 2 4 L5 = malloc 2 4
malloc 3 1 L6 = malloc 3 1
malloc 3 2 L7 = malloc 3 2
malloc 3 4 L8 = malloc 3 4
malloc 128 1 L9 = malloc 128 1
malloc 128 2 L10 = malloc 128 2
malloc 128 4 L11 = malloc 128 4
malloc 128 128 L12 = malloc 128 128
malloc 2048 1 L13 = malloc 2048 1
malloc 2048 2 L14 = malloc 2048 2
malloc 2048 4 L15 = malloc 2048 4
malloc 3968 1 L16 = malloc 3968 1
malloc 3968 2 L17 = malloc 3968 2
malloc 3968 4 L18 = malloc 3968 4
malloc 0 1 L19 = malloc 0 1

View File

@ -1,275 +1,272 @@
# This file was generated by a slightly extended version of a script L1 = malloc 32 2
# attached to https://reviews.llvm.org/D47508. free L1
L2 = malloc 3 4
malloc 2 4 L3 = malloc 3 128
malloc 4095 128 free L3
malloc 3 16 free L2
malloc 8192 2 L4 = malloc 2 16
malloc 1 128 free L4
malloc 3 2 L5 = malloc 4097 4
free 3 free L5
free 3 L6 = malloc 2 2
malloc 32 2 L7 = malloc 3 2
malloc 2 16 L8 = malloc 32 16
free 1 free L6
malloc 2048 2 free L8
free 2 free L7
malloc 2049 4 L9 = malloc 8192 2
malloc 4097 2 L10 = malloc 33 4
malloc 2 16 free L9
free 1 L11 = malloc 2047 2
free 6 L12 = malloc 5 16
malloc 1 16 L13 = malloc 4 16
malloc 33 128 L14 = malloc 2048 2
malloc 2 128 free L10
malloc 2 16 L15 = malloc 4 128
malloc 2 4 free L13
malloc 2 4 L16 = malloc 1 2
free 4 L17 = malloc 4095 128
malloc 4 4 free L12
malloc 2 16 free L15
free 3 L18 = malloc 0 128
malloc 0 128 L19 = malloc 2 128
free 6 L20 = malloc 4096 2
free 2 L21 = malloc 2 2
malloc 33 2 L22 = malloc 8192 128
malloc 4095 2 L23 = malloc 4 2
free 6 L24 = malloc 4097 4
malloc 2 4 free L19
malloc 0 2 free L20
free 1 L25 = malloc 3 128
free 9 free L23
free 5 free L21
malloc 32 2 free L22
malloc 4096 2 free L25
free 2 free L16
free 9 L26 = malloc 1 128
free 6 L27 = malloc 4096 4
malloc 8192 16 free L14
malloc 2 4 L28 = malloc 31 2
malloc 4096 16 free L24
free 10 L29 = malloc 2048 128
malloc 4 4 free L28
free 7 free L11
malloc 4 4 L30 = malloc 4 2
malloc 8193 2 L31 = malloc 32 16
malloc 1 2 L32 = malloc 1 4
free 3 free L30
free 7 L33 = malloc 3 2
malloc 4096 2 L34 = malloc 4096 4
free 0 free L17
malloc 4096 4 free L18
free 3 free L32
malloc 4097 128 L35 = malloc 4097 4
malloc 1 2 L36 = malloc 8193 2
malloc 4 2 L37 = malloc 3 2
free 10 free L34
free 8 L38 = malloc 8193 16
malloc 0 16 L39 = malloc 4096 4
malloc 2049 16 L40 = malloc 8192 16
free 9 L41 = malloc 32 4
malloc 8193 16 free L26
free 10 free L38
free 1 free L37
malloc 8193 2 L42 = malloc 0 2
free 11 free L31
malloc 3 16 free L40
free 5 free L36
malloc 33 128 free L35
free 0 L43 = malloc 2047 2
malloc 2049 4 free L41
malloc 1 128 L44 = malloc 4 4
malloc 32 16 free L43
free 1 free L33
free 9 free L42
malloc 2048 4 L45 = malloc 4097 16
free 0 free L27
free 2 L46 = malloc 32 128
malloc 5 4 L47 = malloc 8191 16
free 11 L48 = malloc 1 16
malloc 2048 4 L49 = malloc 32 128
malloc 4097 16 L50 = malloc 3 2
malloc 8192 4 L51 = malloc 4096 128
free 2 free L51
free 8 L52 = malloc 2048 4
free 11 free L29
malloc 8192 4 L53 = malloc 4097 128
free 2 free L44
malloc 8191 4 L54 = malloc 1 16
malloc 32 128 L55 = malloc 4095 16
free 7 L56 = malloc 2047 2
malloc 4 16 L57 = malloc 0 2
malloc 4096 128 L58 = malloc 2048 2
free 12 free L48
malloc 2 4 L59 = malloc 1 4
free 9 L60 = malloc 32 16
malloc 8193 128 free L50
malloc 4095 4 L61 = malloc 1 4
malloc 2049 16 L62 = malloc 4096 2
malloc 2 4 free L60
free 16 L63 = malloc 1 16
malloc 0 128 L64 = malloc 32 128
malloc 5 2 free L55
malloc 2047 4 L65 = malloc 8192 16
malloc 2 2 free L57
free 10 L66 = malloc 1 128
malloc 0 128 free L65
free 6 free L61
malloc 2047 128 free L45
free 11 free L64
free 0 free L39
free 9 L67 = malloc 2048 2
malloc 4 4 free L47
malloc 3 2 L68 = malloc 2049 4
free 7 free L63
malloc 1 128 free L68
free 13 free L54
malloc 8193 16 free L59
malloc 4097 128 free L52
free 15 L69 = malloc 2 2
free 3 L70 = malloc 8192 16
malloc 1 2 L71 = malloc 2049 16
malloc 2049 4 L72 = malloc 3 16
malloc 2048 2 L73 = malloc 4097 16
free 7 L74 = malloc 4096 2
malloc 31 4 L75 = malloc 4097 4
free 5 free L67
free 14 free L71
free 4 free L72
free 10 free L75
malloc 4 4 free L74
free 6 L76 = malloc 3 4
malloc 3 2 free L70
malloc 1 128 free L69
free 13 L77 = malloc 4 4
malloc 4 16 free L49
free 4 L78 = malloc 4096 16
free 8 L79 = malloc 33 2
malloc 3 16 free L76
free 13 L80 = malloc 2 16
malloc 0 4 free L58
free 8 free L80
free 13 free L56
malloc 1 2 L81 = malloc 1 128
malloc 8192 128 free L73
free 12 L82 = malloc 1 16
malloc 2049 2 free L53
malloc 1 16 free L81
free 4 free L77
free 7 L83 = malloc 2 2
malloc 4 16 L84 = malloc 3 16
malloc 4 128 free L62
malloc 4096 16 L85 = malloc 2049 2
malloc 2048 16 free L83
malloc 32 4 L86 = malloc 3 4
malloc 8193 4 L87 = malloc 4096 128
free 2 free L86
malloc 3 16 L88 = malloc 3 2
malloc 8192 4 free L82
free 1 free L66
malloc 8191 2 free L84
free 3 L89 = malloc 8192 4
malloc 8192 2 free L88
malloc 8192 2 L90 = malloc 3 4
free 3 L91 = malloc 1 4
free 7 L92 = malloc 4097 4
malloc 31 4 L93 = malloc 5 16
malloc 2049 2 L94 = malloc 2 128
free 4 L95 = malloc 4096 2
free 3 L96 = malloc 32 16
free 14 L97 = malloc 8192 16
free 1 L98 = malloc 32 128
malloc 2048 4 free L90
malloc 1 4 free L79
malloc 1 4 L99 = malloc 8193 4
malloc 2 4 free L46
malloc 4 16 L100 = malloc 31 4
free 12 L101 = malloc 8192 128
free 14 free L99
free 3 L102 = malloc 2049 16
free 0 L103 = malloc 4 2
free 12 L104 = malloc 32 2
free 10 free L101
malloc 32 16 free L98
free 5 L105 = malloc 1 16
free 9 free L92
free 4 L106 = malloc 2 2
free 9 L107 = malloc 31 16
free 3 L108 = malloc 2 4
malloc 4096 16 free L94
malloc 4 2 L109 = malloc 4097 4
free 12 L110 = malloc 31 4
free 10 free L103
free 3 L111 = malloc 31 4
free 7 free L111
malloc 4097 4 L112 = malloc 2049 2
malloc 4095 16 L113 = malloc 32 128
free 3 free L106
malloc 2047 16 L114 = malloc 8191 2
free 12 free L105
malloc 8193 2 free L97
free 2 free L109
free 3 L115 = malloc 2 16
malloc 0 4 free L78
free 2 free L93
free 9 free L114
malloc 8192 16 free L115
malloc 2 2 free L96
malloc 4096 4 free L85
malloc 5 128 L116 = malloc 2 16
malloc 4095 4 free L89
malloc 4095 4 free L87
free 9 L117 = malloc 33 2
malloc 32 4 L118 = malloc 1 4
malloc 31 16 L119 = malloc 4096 128
free 15 free L107
malloc 4097 16 L120 = malloc 8192 4
malloc 2048 128 L121 = malloc 1 128
malloc 2048 2 L122 = malloc 3 4
malloc 4096 128 L123 = malloc 2047 4
malloc 3 16 L124 = malloc 2 2
free 2 free L121
malloc 1 4 free L102
malloc 3 4 L125 = malloc 2 4
free 3 L126 = malloc 1 16
malloc 31 2 L127 = malloc 2048 2
malloc 1 128 L128 = malloc 2048 16
free 21 L129 = malloc 32 128
malloc 0 128 free L124
free 8 L130 = malloc 2048 16
malloc 3 128 L131 = malloc 32 16
free 5 L132 = malloc 32 128
malloc 1 16 free L100
free 9 free L117
malloc 2048 4 free L126
free 8 L133 = malloc 8192 4
free 4 L134 = malloc 8192 2
malloc 31 2 L135 = malloc 2 16
malloc 1 16 free L119
free 19 L136 = malloc 31 16
malloc 2 4 free L118
malloc 2 2 free L125
free 8 free L132
malloc 8193 16 free L122
free 11 free L134
free 8 free L136
free 6 free L130
free 12 free L110
free 4 free L123
free 0 free L104
free 10 free L116
free 1 free L133
free 0 free L91
free 5 free L113
free 5 free L128
free 3 free L129
free 6 free L95
free 1 free L131
free 2 free L127
free 6 free L112
free 5 free L108
free 4 free L135
free 3 free L120
free 1
free 1
free 0

View File

@ -1,10 +1,10 @@
malloc 8 16 L1 = malloc 8 16
malloc 16 8 L2 = malloc 16 8
malloc 64 32 L3 = malloc 64 32
malloc 1 8 L4 = malloc 1 8
malloc 64 32 L5 = malloc 64 32
malloc 64 8 L6 = malloc 64 8
malloc 1024 32 L7 = malloc 1024 32
malloc 1 16 L8 = malloc 1 16
malloc 8 16 L9 = malloc 8 16
malloc 1024 16 L10 = malloc 1024 16

View File

@ -167,13 +167,25 @@ static cl::opt<bool> UseHostOnlyAllocationPolicy(
cl::init(false), cl::sub(IRMemoryMapSubcommand)); cl::init(false), cl::sub(IRMemoryMapSubcommand));
using AllocationT = std::pair<addr_t, addr_t>; using AllocationT = std::pair<addr_t, addr_t>;
bool areAllocationsOverlapping(const AllocationT &L, const AllocationT &R);
using AddrIntervalMap = using AddrIntervalMap =
IntervalMap<addr_t, unsigned, 8, IntervalMapHalfOpenInfo<addr_t>>; IntervalMap<addr_t, unsigned, 8, IntervalMapHalfOpenInfo<addr_t>>;
bool evalMalloc(IRMemoryMap &IRMemMap, StringRef Line,
AddrIntervalMap &AllocatedIntervals); struct IRMemoryMapTestState {
bool evalFree(IRMemoryMap &IRMemMap, StringRef Line, TargetSP Target;
AddrIntervalMap &AllocatedIntervals); IRMemoryMap Map;
AddrIntervalMap::Allocator IntervalMapAllocator;
AddrIntervalMap Allocations;
StringMap<addr_t> Label2AddrMap;
IRMemoryMapTestState(TargetSP Target)
: Target(Target), Map(Target), Allocations(IntervalMapAllocator) {}
};
bool areAllocationsOverlapping(const AllocationT &L, const AllocationT &R);
bool evalMalloc(StringRef Line, IRMemoryMapTestState &State);
bool evalFree(StringRef Line, IRMemoryMapTestState &State);
int evaluateMemoryMapCommands(Debugger &Dbg); int evaluateMemoryMapCommands(Debugger &Dbg);
} // namespace irmemorymap } // namespace irmemorymap
@ -514,17 +526,23 @@ bool opts::irmemorymap::areAllocationsOverlapping(const AllocationT &L,
return R.first < L.second && L.first < R.second; return R.first < L.second && L.first < R.second;
} }
bool opts::irmemorymap::evalMalloc(IRMemoryMap &IRMemMap, StringRef Line, bool opts::irmemorymap::evalMalloc(StringRef Line,
AddrIntervalMap &AllocatedIntervals) { IRMemoryMapTestState &State) {
// ::= malloc <size> <alignment> // ::= <label> = malloc <size> <alignment>
StringRef Label;
std::tie(Label, Line) = Line.split('=');
if (Line.empty())
return false;
Label = Label.trim();
Line = Line.trim();
size_t Size; size_t Size;
uint8_t Alignment; uint8_t Alignment;
int Matches = sscanf(Line.data(), "malloc %zu %hhu", &Size, &Alignment); int Matches = sscanf(Line.data(), "malloc %zu %hhu", &Size, &Alignment);
if (Matches != 2) if (Matches != 2)
return false; return false;
outs() << formatv("Command: malloc(size={0}, alignment={1})\n", Size, outs() << formatv("Command: {0} = malloc(size={1}, alignment={2})\n", Label,
Alignment); Size, Alignment);
if (!isPowerOf2_32(Alignment)) { if (!isPowerOf2_32(Alignment)) {
outs() << "Malloc error: alignment is not a power of 2\n"; outs() << "Malloc error: alignment is not a power of 2\n";
exit(1); exit(1);
@ -539,7 +557,7 @@ bool opts::irmemorymap::evalMalloc(IRMemoryMap &IRMemMap, StringRef Line,
const bool ZeroMemory = false; const bool ZeroMemory = false;
Status ST; Status ST;
addr_t Addr = addr_t Addr =
IRMemMap.Malloc(Size, Alignment, Permissions, AP, ZeroMemory, ST); State.Map.Malloc(Size, Alignment, Permissions, AP, ZeroMemory, ST);
if (ST.Fail()) { if (ST.Fail()) {
outs() << formatv("Malloc error: {0}\n", ST); outs() << formatv("Malloc error: {0}\n", ST);
return true; return true;
@ -557,10 +575,10 @@ bool opts::irmemorymap::evalMalloc(IRMemoryMap &IRMemMap, StringRef Line,
// Check that the allocation does not overlap another allocation. Do so by // Check that the allocation does not overlap another allocation. Do so by
// testing each allocation which may cover the interval [Addr, EndOfRegion). // testing each allocation which may cover the interval [Addr, EndOfRegion).
addr_t EndOfRegion = Addr + Size; addr_t EndOfRegion = Addr + Size;
auto Probe = AllocatedIntervals.begin(); auto Probe = State.Allocations.begin();
Probe.advanceTo(Addr); //< First interval s.t stop >= Addr. Probe.advanceTo(Addr); //< First interval s.t stop >= Addr.
AllocationT NewAllocation = {Addr, EndOfRegion}; AllocationT NewAllocation = {Addr, EndOfRegion};
while (Probe != AllocatedIntervals.end() && Probe.start() < EndOfRegion) { while (Probe != State.Allocations.end() && Probe.start() < EndOfRegion) {
AllocationT ProbeAllocation = {Probe.start(), Probe.stop()}; AllocationT ProbeAllocation = {Probe.start(), Probe.stop()};
if (areAllocationsOverlapping(ProbeAllocation, NewAllocation)) { if (areAllocationsOverlapping(ProbeAllocation, NewAllocation)) {
outs() << "Malloc error: overlapping allocation detected" outs() << "Malloc error: overlapping allocation detected"
@ -575,41 +593,42 @@ bool opts::irmemorymap::evalMalloc(IRMemoryMap &IRMemMap, StringRef Line,
// to inhibit interval coalescing. // to inhibit interval coalescing.
static unsigned AllocationID = 0; static unsigned AllocationID = 0;
if (Size) if (Size)
AllocatedIntervals.insert(Addr, EndOfRegion, AllocationID++); State.Allocations.insert(Addr, EndOfRegion, AllocationID++);
// Store the label -> address mapping.
State.Label2AddrMap[Label] = Addr;
return true; return true;
} }
bool opts::irmemorymap::evalFree(IRMemoryMap &IRMemMap, StringRef Line, bool opts::irmemorymap::evalFree(StringRef Line, IRMemoryMapTestState &State) {
AddrIntervalMap &AllocatedIntervals) { // ::= free <label>
// ::= free <allocation-index> if (!Line.consume_front("free"))
size_t AllocIndex;
int Matches = sscanf(Line.data(), "free %zu", &AllocIndex);
if (Matches != 1)
return false; return false;
StringRef Label = Line.trim();
outs() << formatv("Command: free(allocation-index={0})\n", AllocIndex); outs() << formatv("Command: free({0})\n", Label);
auto LabelIt = State.Label2AddrMap.find(Label);
// Find and free the AllocIndex-th allocation. if (LabelIt == State.Label2AddrMap.end()) {
auto Probe = AllocatedIntervals.begin(); outs() << "Free error: Invalid allocation label\n";
for (size_t I = 0; I < AllocIndex && Probe != AllocatedIntervals.end(); ++I)
++Probe;
if (Probe == AllocatedIntervals.end()) {
outs() << "Free error: Invalid allocation index\n";
exit(1); exit(1);
} }
Status ST; Status ST;
IRMemMap.Free(Probe.start(), ST); addr_t Addr = LabelIt->getValue();
State.Map.Free(Addr, ST);
if (ST.Fail()) { if (ST.Fail()) {
outs() << formatv("Free error: {0}\n", ST); outs() << formatv("Free error: {0}\n", ST);
exit(1); exit(1);
} }
// Erase the allocation from the live interval map. // Erase the allocation from the live interval map.
outs() << formatv("Free: [{0:x}, {1:x})\n", Probe.start(), Probe.stop()); auto Interval = State.Allocations.find(Addr);
Probe.erase(); if (Interval != State.Allocations.end()) {
outs() << formatv("Free: [{0:x}, {1:x})\n", Interval.start(),
Interval.stop());
Interval.erase();
}
return true; return true;
} }
@ -638,9 +657,7 @@ int opts::irmemorymap::evaluateMemoryMapCommands(Debugger &Dbg) {
} }
// Set up an IRMemoryMap and associated testing state. // Set up an IRMemoryMap and associated testing state.
IRMemoryMap IRMemMap(Target); IRMemoryMapTestState State(Target);
AddrIntervalMap::Allocator AIMapAllocator;
AddrIntervalMap AllocatedIntervals(AIMapAllocator);
// Parse and apply commands from the command file. // Parse and apply commands from the command file.
std::unique_ptr<MemoryBuffer> MB = opts::openFile(irmemorymap::CommandFile); std::unique_ptr<MemoryBuffer> MB = opts::openFile(irmemorymap::CommandFile);
@ -653,10 +670,10 @@ int opts::irmemorymap::evaluateMemoryMapCommands(Debugger &Dbg) {
if (Line.empty() || Line[0] == '#') if (Line.empty() || Line[0] == '#')
continue; continue;
if (evalMalloc(IRMemMap, Line, AllocatedIntervals)) if (evalMalloc(Line, State))
continue; continue;
if (evalFree(IRMemMap, Line, AllocatedIntervals)) if (evalFree(Line, State))
continue; continue;
errs() << "Could not parse line: " << Line << "\n"; errs() << "Could not parse line: " << Line << "\n";