Skip to content

Commit

Permalink
Revert "[memprof] Record BuildIDs in the raw profile."
Browse files Browse the repository at this point in the history
This reverts commit 287177a.
  • Loading branch information
snehasish committed Mar 13, 2023
1 parent 223ec28 commit debe80c
Show file tree
Hide file tree
Showing 26 changed files with 61 additions and 90 deletions.
Binary file modified clang/test/CodeGen/Inputs/memprof.exe
Binary file not shown.
Binary file modified clang/test/CodeGen/Inputs/memprof.memprofraw
Binary file not shown.
26 changes: 10 additions & 16 deletions compiler-rt/include/profile/MemProfData.inc
Expand Up @@ -19,7 +19,6 @@
* synced up.
*
\*===----------------------------------------------------------------------===*/
#include <string.h>

#ifdef _MSC_VER
#define PACKED(...) __pragma(pack(push,1)) __VA_ARGS__ __pragma(pack(pop))
Expand All @@ -33,9 +32,7 @@
(uint64_t)'o' << 24 | (uint64_t)'f' << 16 | (uint64_t)'r' << 8 | (uint64_t)129)

// The version number of the raw binary format.
#define MEMPROF_RAW_VERSION 3ULL

#define MEMPROF_BUILDID_MAX_SIZE 32ULL
#define MEMPROF_RAW_VERSION 2ULL

namespace llvm {
namespace memprof {
Expand All @@ -49,40 +46,37 @@ PACKED(struct Header {
uint64_t StackOffset;
});


// A struct describing the information necessary to describe a /proc/maps
// segment entry for a particular binary/library identified by its build id.
PACKED(struct SegmentEntry {
uint64_t Start;
uint64_t End;
uint64_t Offset;
uint64_t BuildIdSize;
uint8_t BuildId[MEMPROF_BUILDID_MAX_SIZE] = {0};
// This field is unused until sanitizer procmaps support for build ids for
// Linux-Elf is implemented.
uint8_t BuildId[32] = {0};

// This constructor is only used in tests so don't set the BuildId.
SegmentEntry(uint64_t S, uint64_t E, uint64_t O)
: Start(S), End(E), Offset(O), BuildIdSize(0) {}
SegmentEntry(uint64_t S, uint64_t E, uint64_t O) :
Start(S), End(E), Offset(O) {}

SegmentEntry(const SegmentEntry& S) {
Start = S.Start;
End = S.End;
Offset = S.Offset;
BuildIdSize = S.BuildIdSize;
memcpy(BuildId, S.BuildId, S.BuildIdSize);
}

SegmentEntry& operator=(const SegmentEntry& S) {
Start = S.Start;
End = S.End;
Offset = S.Offset;
BuildIdSize = S.BuildIdSize;
memcpy(BuildId, S.BuildId, S.BuildIdSize);
return *this;
}

bool operator==(const SegmentEntry& S) const {
return Start == S.Start && End == S.End && Offset == S.Offset &&
BuildIdSize == S.BuildIdSize &&
memcmp(BuildId, S.BuildId, S.BuildIdSize) == 0;
return Start == S.Start &&
End == S.End &&
Offset == S.Offset;
}
});

Expand Down
7 changes: 3 additions & 4 deletions compiler-rt/lib/memprof/memprof_allocator.cpp
Expand Up @@ -23,11 +23,11 @@
#include "sanitizer_common/sanitizer_allocator_checks.h"
#include "sanitizer_common/sanitizer_allocator_interface.h"
#include "sanitizer_common/sanitizer_allocator_report.h"
#include "sanitizer_common/sanitizer_common.h"
#include "sanitizer_common/sanitizer_errno.h"
#include "sanitizer_common/sanitizer_file.h"
#include "sanitizer_common/sanitizer_flags.h"
#include "sanitizer_common/sanitizer_internal_defs.h"
#include "sanitizer_common/sanitizer_procmaps.h"
#include "sanitizer_common/sanitizer_stackdepot.h"

#include <sched.h>
Expand Down Expand Up @@ -295,9 +295,8 @@ struct Allocator {
// memprof_rawprofile.h.
char *Buffer = nullptr;

__sanitizer::ListOfModules Modules;
Modules.init();
u64 BytesSerialized = SerializeToRawProfile(MIBMap, Modules, Buffer);
MemoryMappingLayout Layout(/*cache_enabled=*/true);
u64 BytesSerialized = SerializeToRawProfile(MIBMap, Layout, Buffer);
CHECK(Buffer && BytesSerialized && "could not serialize to buffer");
report_file.Write(Buffer, BytesSerialized);
}
Expand Down
45 changes: 20 additions & 25 deletions compiler-rt/lib/memprof/memprof_rawprofile.cpp
Expand Up @@ -33,14 +33,12 @@ void RecordStackId(const uptr Key, UNUSED LockedMemInfoBlock *const &MIB,
}
} // namespace

u64 SegmentSizeBytes(__sanitizer::ListOfModules &Modules) {
u64 SegmentSizeBytes(MemoryMappingLayoutBase &Layout) {
u64 NumSegmentsToRecord = 0;
for (const auto &Module : Modules) {
for (const auto &Segment : Module.ranges()) {
if (Segment.executable)
NumSegmentsToRecord++;
}
}
MemoryMappedSegment segment;
for (Layout.Reset(); Layout.Next(&segment);)
if (segment.IsReadable() && segment.IsExecutable())
NumSegmentsToRecord++;

return sizeof(u64) // A header which stores the number of records.
+ sizeof(SegmentEntry) * NumSegmentsToRecord;
Expand All @@ -53,31 +51,28 @@ u64 SegmentSizeBytes(__sanitizer::ListOfModules &Modules) {
// Start
// End
// Offset
// UuidSize
// Uuid 32B
// BuildID 32B
// ----------
// ...
void SerializeSegmentsToBuffer(__sanitizer::ListOfModules &Modules,
void SerializeSegmentsToBuffer(MemoryMappingLayoutBase &Layout,
const u64 ExpectedNumBytes, char *&Buffer) {
char *Ptr = Buffer;
// Reserve space for the final count.
Ptr += sizeof(u64);

u64 NumSegmentsRecorded = 0;

for (const auto &Module : Modules) {
for (const auto &Segment : Module.ranges()) {
if (Segment.executable) {
SegmentEntry Entry(Segment.beg, Segment.end, Module.base_address());
CHECK(Module.uuid_size() <= MEMPROF_BUILDID_MAX_SIZE);
Entry.BuildIdSize = Module.uuid_size();
memcpy(Entry.BuildId, Module.uuid(), Module.uuid_size());
memcpy(Ptr, &Entry, sizeof(SegmentEntry));
Ptr += sizeof(SegmentEntry);
NumSegmentsRecorded++;
}
MemoryMappedSegment segment;

for (Layout.Reset(); Layout.Next(&segment);) {
if (segment.IsReadable() && segment.IsExecutable()) {
// TODO: Record segment.uuid when it is implemented for Linux-Elf.
SegmentEntry Entry(segment.start, segment.end, segment.offset);
memcpy(Ptr, &Entry, sizeof(SegmentEntry));
Ptr += sizeof(SegmentEntry);
NumSegmentsRecorded++;
}
}

// Store the number of segments we recorded in the space we reserved.
*((u64 *)Buffer) = NumSegmentsRecorded;
CHECK(ExpectedNumBytes >= static_cast<u64>(Ptr - Buffer) &&
Expand Down Expand Up @@ -203,11 +198,11 @@ void SerializeMIBInfoToBuffer(MIBMapTy &MIBMap, const Vector<u64> &StackIds,
// ----------
// Optional Padding Bytes
// ...
u64 SerializeToRawProfile(MIBMapTy &MIBMap, __sanitizer::ListOfModules &Modules,
u64 SerializeToRawProfile(MIBMapTy &MIBMap, MemoryMappingLayoutBase &Layout,
char *&Buffer) {
// Each section size is rounded up to 8b since the first entry in each section
// is a u64 which holds the number of entries in the section by convention.
const u64 NumSegmentBytes = RoundUpTo(SegmentSizeBytes(Modules), 8);
const u64 NumSegmentBytes = RoundUpTo(SegmentSizeBytes(Layout), 8);

Vector<u64> StackIds;
MIBMap.ForEach(RecordStackId, reinterpret_cast<void *>(&StackIds));
Expand Down Expand Up @@ -237,7 +232,7 @@ u64 SerializeToRawProfile(MIBMapTy &MIBMap, __sanitizer::ListOfModules &Modules,
sizeof(Header) + NumSegmentBytes + NumMIBInfoBytes};
Ptr = WriteBytes(header, Ptr);

SerializeSegmentsToBuffer(Modules, NumSegmentBytes, Ptr);
SerializeSegmentsToBuffer(Layout, NumSegmentBytes, Ptr);
Ptr += NumSegmentBytes;

SerializeMIBInfoToBuffer(MIBMap, StackIds, NumMIBInfoBytes, Ptr);
Expand Down
6 changes: 3 additions & 3 deletions compiler-rt/lib/memprof/memprof_rawprofile.h
Expand Up @@ -2,13 +2,13 @@
#define MEMPROF_RAWPROFILE_H_

#include "memprof_mibmap.h"
#include "sanitizer_common/sanitizer_common.h"
#include "sanitizer_common/sanitizer_procmaps.h"

namespace __memprof {
// Serialize the in-memory representation of the memprof profile to the raw
// binary format. The format itself is documented memprof_rawprofile.cpp.
u64 SerializeToRawProfile(MIBMapTy &BlockCache,
__sanitizer::ListOfModules &Modules, char *&Buffer);
u64 SerializeToRawProfile(MIBMapTy &BlockCache, MemoryMappingLayoutBase &Layout,
char *&Buffer);
} // namespace __memprof

#endif // MEMPROF_RAWPROFILE_H_
26 changes: 10 additions & 16 deletions llvm/include/llvm/ProfileData/MemProfData.inc
Expand Up @@ -19,7 +19,6 @@
* synced up.
*
\*===----------------------------------------------------------------------===*/
#include <string.h>

#ifdef _MSC_VER
#define PACKED(...) __pragma(pack(push,1)) __VA_ARGS__ __pragma(pack(pop))
Expand All @@ -33,9 +32,7 @@
(uint64_t)'o' << 24 | (uint64_t)'f' << 16 | (uint64_t)'r' << 8 | (uint64_t)129)

// The version number of the raw binary format.
#define MEMPROF_RAW_VERSION 3ULL

#define MEMPROF_BUILDID_MAX_SIZE 32ULL
#define MEMPROF_RAW_VERSION 2ULL

namespace llvm {
namespace memprof {
Expand All @@ -49,40 +46,37 @@ PACKED(struct Header {
uint64_t StackOffset;
});


// A struct describing the information necessary to describe a /proc/maps
// segment entry for a particular binary/library identified by its build id.
PACKED(struct SegmentEntry {
uint64_t Start;
uint64_t End;
uint64_t Offset;
uint64_t BuildIdSize;
uint8_t BuildId[MEMPROF_BUILDID_MAX_SIZE] = {0};
// This field is unused until sanitizer procmaps support for build ids for
// Linux-Elf is implemented.
uint8_t BuildId[32] = {0};

// This constructor is only used in tests so don't set the BuildId.
SegmentEntry(uint64_t S, uint64_t E, uint64_t O)
: Start(S), End(E), Offset(O), BuildIdSize(0) {}
SegmentEntry(uint64_t S, uint64_t E, uint64_t O) :
Start(S), End(E), Offset(O) {}

SegmentEntry(const SegmentEntry& S) {
Start = S.Start;
End = S.End;
Offset = S.Offset;
BuildIdSize = S.BuildIdSize;
memcpy(BuildId, S.BuildId, S.BuildIdSize);
}

SegmentEntry& operator=(const SegmentEntry& S) {
Start = S.Start;
End = S.End;
Offset = S.Offset;
BuildIdSize = S.BuildIdSize;
memcpy(BuildId, S.BuildId, S.BuildIdSize);
return *this;
}

bool operator==(const SegmentEntry& S) const {
return Start == S.Start && End == S.End && Offset == S.Offset &&
BuildIdSize == S.BuildIdSize &&
memcmp(BuildId, S.BuildId, S.BuildIdSize) == 0;
return Start == S.Start &&
End == S.End &&
Offset == S.Offset;
}
});

Expand Down
6 changes: 4 additions & 2 deletions llvm/lib/ProfileData/RawMemProfReader.cpp
Expand Up @@ -158,13 +158,15 @@ bool isRuntimePath(const StringRef Path) {
}

std::string getBuildIdString(const SegmentEntry &Entry) {
constexpr size_t Size = sizeof(Entry.BuildId) / sizeof(uint8_t);
constexpr uint8_t Zeros[Size] = {0};
// If the build id is unset print a helpful string instead of all zeros.
if (Entry.BuildIdSize == 0)
if (memcmp(Entry.BuildId, Zeros, Size) == 0)
return "<None>";

std::string Str;
raw_string_ostream OS(Str);
for (size_t I = 0; I < Entry.BuildIdSize; I++) {
for (size_t I = 0; I < Size; I++) {
OS << format_hex_no_prefix(Entry.BuildId[I], 2);
}
return OS.str();
Expand Down
Binary file modified llvm/test/Transforms/PGOProfile/Inputs/memprof.exe
Binary file not shown.
Binary file modified llvm/test/Transforms/PGOProfile/Inputs/memprof.memprofraw
Binary file not shown.
Binary file modified llvm/test/Transforms/PGOProfile/Inputs/memprof_pgo.profraw
Binary file not shown.
Binary file modified llvm/test/tools/llvm-profdata/Inputs/basic.memprofexe
Binary file not shown.
Binary file modified llvm/test/tools/llvm-profdata/Inputs/basic.memprofraw
Binary file not shown.
Binary file not shown.
Binary file removed llvm/test/tools/llvm-profdata/Inputs/buildid.memprofraw
Binary file not shown.
Binary file modified llvm/test/tools/llvm-profdata/Inputs/inline.memprofexe
Binary file not shown.
Binary file modified llvm/test/tools/llvm-profdata/Inputs/inline.memprofraw
Binary file not shown.
Binary file modified llvm/test/tools/llvm-profdata/Inputs/multi.memprofexe
Binary file not shown.
Binary file modified llvm/test/tools/llvm-profdata/Inputs/multi.memprofraw
Binary file not shown.
Binary file modified llvm/test/tools/llvm-profdata/Inputs/pic.memprofexe
Binary file not shown.
Binary file modified llvm/test/tools/llvm-profdata/Inputs/pic.memprofraw
Binary file not shown.
Expand Up @@ -72,7 +72,6 @@ INPUTS["basic"]="BASIC"
INPUTS["inline"]="INLINE"
INPUTS["multi"]="MULTI"
INPUTS["pic"]="BASIC;-pie"
INPUTS["buildid"]="BASIC;-Wl,-build-id=sha1"

for name in "${!INPUTS[@]}"; do
IFS=";" read -r src flags <<< "${INPUTS[$name]}"
Expand Down
10 changes: 5 additions & 5 deletions llvm/test/tools/llvm-profdata/memprof-basic.test
Expand Up @@ -8,17 +8,17 @@ additional allocations which do not originate from the main binary are pruned.

CHECK: MemprofProfile:
CHECK-NEXT: Summary:
CHECK-NEXT: Version: 3
CHECK-NEXT: Version: 2
CHECK-NEXT: NumSegments: {{[0-9]+}}
CHECK-NEXT: NumMibInfo: 2
CHECK-NEXT: NumAllocFunctions: 1
CHECK-NEXT: NumStackOffsets: 2
CHECK-NEXT: Segments:
CHECK-NEXT: -
CHECK-NEXT: BuildId: {{[[:xdigit:]]+}}
CHECK-NEXT: Start: 0x{{[[:xdigit:]]+}}
CHECK-NEXT: End: 0x{{[[:xdigit:]]+}}
CHECK-NEXT: Offset: 0x{{[[:xdigit:]]+}}
CHECK-NEXT: BuildId: <None>
CHECK-NEXT: Start: 0x{{[0-9]+}}
CHECK-NEXT: End: 0x{{[0-9]+}}
CHECK-NEXT: Offset: 0x{{[0-9]+}}
CHECK-NEXT: -

CHECK: Records:
Expand Down
12 changes: 0 additions & 12 deletions llvm/test/tools/llvm-profdata/memprof-buildid.test

This file was deleted.

10 changes: 5 additions & 5 deletions llvm/test/tools/llvm-profdata/memprof-inline.test
Expand Up @@ -5,17 +5,17 @@ RUN: llvm-profdata show --memory %p/Inputs/inline.memprofraw --profiled-binary %

CHECK: MemprofProfile:
CHECK-NEXT: Summary:
CHECK-NEXT: Version: 3
CHECK-NEXT: Version: 2
CHECK-NEXT: NumSegments: {{[0-9]+}}
CHECK-NEXT: NumMibInfo: 2
CHECK-NEXT: NumAllocFunctions: 2
CHECK-NEXT: NumStackOffsets: 1
CHECK-NEXT: Segments:
CHECK-NEXT: -
CHECK-NEXT: BuildId: {{[[:xdigit:]]+}}
CHECK-NEXT: Start: 0x{{[[:xdigit:]]+}}
CHECK-NEXT: End: 0x{{[[:xdigit:]]+}}
CHECK-NEXT: Offset: 0x{{[[:xdigit:]]+}}
CHECK-NEXT: BuildId: <None>
CHECK-NEXT: Start: 0x{{[0-9]+}}
CHECK-NEXT: End: 0x{{[0-9]+}}
CHECK-NEXT: Offset: 0x{{[0-9]+}}
CHECK-NEXT: -

CHECK: Records:
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/tools/llvm-profdata/memprof-multi.test
Expand Up @@ -7,7 +7,7 @@ We expect 2 MIB entries, 1 each for the malloc calls in the program.

CHECK: MemprofProfile:
CHECK-NEXT: Summary:
CHECK-NEXT: Version: 3
CHECK-NEXT: Version: 2
CHECK-NEXT: NumSegments: {{[0-9]+}}
CHECK-NEXT: NumMibInfo: 2
CHECK-NEXT: NumAllocFunctions: 1
Expand Down

0 comments on commit debe80c

Please sign in to comment.