Skip to content

Commit bd25451

Browse files
committed
Add basic support for host stack traces
1 parent 852f602 commit bd25451

File tree

4 files changed

+112
-1
lines changed

4 files changed

+112
-1
lines changed

offload/plugins-nextgen/common/include/PluginInterface.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <shared_mutex>
2020
#include <vector>
2121

22+
#include "ExclusiveAccess.h"
2223
#include "Shared/APITypes.h"
2324
#include "Shared/Debug.h"
2425
#include "Shared/Environment.h"
@@ -383,6 +384,14 @@ struct GenericKernelTy {
383384
bool IsBareKernel = false;
384385
};
385386

387+
struct AllocationInfoTy {
388+
std::string AllocationTrace;
389+
std::string DeallocationTrace;
390+
void *HostPtr;
391+
uint64_t Size;
392+
TargetAllocTy Kind;
393+
};
394+
386395
/// Class representing a map of host pinned allocations. We track these pinned
387396
/// allocations, so memory tranfers invloving these buffers can be optimized.
388397
class PinnedAllocationMapTy {
@@ -898,6 +907,8 @@ struct GenericDeviceTy : public DeviceAllocatorTy {
898907
/// Reference to the underlying plugin that created this device.
899908
GenericPluginTy &Plugin;
900909

910+
ProtectedObj<DenseMap<void *, AllocationInfoTy *>> AllocationTraces;
911+
901912
private:
902913
/// Get and set the stack size and heap size for the device. If not used, the
903914
/// plugin can implement the setters as no-op and setting the output
@@ -921,7 +932,6 @@ struct GenericDeviceTy : public DeviceAllocatorTy {
921932

922933
/// Pointer to the memory manager or nullptr if not available.
923934
MemoryManagerTy *MemoryManager;
924-
925935
/// Environment variables defined by the OpenMP standard.
926936
Int32Envar OMP_TeamLimit;
927937
Int32Envar OMP_NumTeams;

offload/plugins-nextgen/common/src/PluginInterface.cpp

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
#include "Utils/ELF.h"
2222
#include "omptarget.h"
2323
#include "llvm/Support/ErrorHandling.h"
24+
#include "llvm/Support/Signals.h"
25+
#include "llvm/Support/raw_ostream.h"
2426
#include <cstdio>
2527
#include <string>
2628

@@ -1380,6 +1382,22 @@ Expected<void *> GenericDeviceTy::dataAlloc(int64_t Size, void *HostPtr,
13801382
if (auto Err = PinnedAllocs.registerHostBuffer(Alloc, Alloc, Size))
13811383
return std::move(Err);
13821384

1385+
std::string StackTrace;
1386+
llvm::raw_string_ostream OS(StackTrace);
1387+
llvm::sys::PrintStackTrace(OS);
1388+
1389+
AllocationInfoTy *AllocationInfo = new AllocationInfoTy();
1390+
AllocationInfo->AllocationTrace = std::move(StackTrace);
1391+
AllocationInfo->HostPtr = HostPtr;
1392+
AllocationInfo->Size = Size;
1393+
AllocationInfo->Kind = Kind;
1394+
1395+
auto AllocationTraceMap = AllocationTraces.getExclusiveAccessor();
1396+
auto *&AI = (*AllocationTraceMap)[Alloc];
1397+
if (AI)
1398+
delete AI;
1399+
AI = AllocationInfo;
1400+
13831401
return Alloc;
13841402
}
13851403

@@ -1388,6 +1406,32 @@ Error GenericDeviceTy::dataDelete(void *TgtPtr, TargetAllocTy Kind) {
13881406
if (Plugin.getRecordReplay().isRecordingOrReplaying())
13891407
return Plugin::success();
13901408

1409+
AllocationInfoTy *AllocationInfo = nullptr;
1410+
{
1411+
auto AllocationTraceMap = AllocationTraces.getExclusiveAccessor();
1412+
AllocationInfo = (*AllocationTraceMap)[TgtPtr];
1413+
}
1414+
1415+
std::string StackTrace;
1416+
llvm::raw_string_ostream OS(StackTrace);
1417+
llvm::sys::PrintStackTrace(OS);
1418+
if (!AllocationInfo) {
1419+
fprintf(stderr, "%s", StackTrace.c_str());
1420+
report_fatal_error("Free of non-allocated memory");
1421+
}
1422+
1423+
if (!AllocationInfo->DeallocationTrace.empty()) {
1424+
fprintf(stderr, "%s", StackTrace.c_str());
1425+
report_fatal_error("double-free");
1426+
}
1427+
1428+
if (AllocationInfo->Kind != Kind) {
1429+
fprintf(stderr, "%s", StackTrace.c_str());
1430+
report_fatal_error("free of wrong kind of memory");
1431+
}
1432+
1433+
AllocationInfo->DeallocationTrace = StackTrace;
1434+
13911435
int Res;
13921436
switch (Kind) {
13931437
case TARGET_ALLOC_DEFAULT:
@@ -2294,6 +2338,22 @@ void GPUSanTy::checkAndReportError() {
22942338
"Allocation[slot:%d,tag:%u,kind:%i]\n%s",
22952339
Green(), STI->PtrSlot, STI->PtrTag, STI->PtrKind, STI->AllocationId,
22962340
STI->AllocationTag, STI->AllocationKind, Default());
2341+
2342+
AllocationInfoTy *AllocationInfo = nullptr;
2343+
if (STI->AllocationStart) {
2344+
auto AllocationTraceMap = Device.AllocationTraces.getExclusiveAccessor();
2345+
AllocationInfo = (*AllocationTraceMap)[STI->AllocationStart];
2346+
}
2347+
if (AllocationInfo) {
2348+
fprintf(stderr, "\nAllocated at\n");
2349+
fprintf(stderr, "%s", AllocationInfo->AllocationTrace.c_str());
2350+
2351+
if (!AllocationInfo->DeallocationTrace.empty()) {
2352+
fprintf(stderr, "\nDeallocated at\n");
2353+
fprintf(stderr, "%s", AllocationInfo->DeallocationTrace.c_str());
2354+
}
2355+
}
2356+
22972357
};
22982358

22992359
switch (STI->ErrorCode) {
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
2+
// clang-format off
3+
// RUN: %libomptarget-compileopt-generic -fsanitize=offload
4+
// RUN: not %libomptarget-run-generic 2>&1 > %t.out
5+
// RUN: %fcheck-generic --check-prefixes=CHECK < %t.out
6+
// clang-format on
7+
8+
// UNSUPPORTED: aarch64-unknown-linux-gnu
9+
// UNSUPPORTED: aarch64-unknown-linux-gnu-LTO
10+
// UNSUPPORTED: x86_64-pc-linux-gnu
11+
// UNSUPPORTED: x86_64-pc-linux-gnu-LTO
12+
// UNSUPPORTED: s390x-ibm-linux-gnu
13+
// UNSUPPORTED: s390x-ibm-linux-gnu-LTO
14+
15+
#include <omp.h>
16+
17+
int main(void) {
18+
void *Ptr = omp_target_alloc(100, 0);
19+
omp_target_free(Ptr, 0);
20+
omp_target_free(Ptr, 0);
21+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
2+
// clang-format off
3+
// RUN: %libomptarget-compileopt-generic -fsanitize=offload
4+
// RUN: not %libomptarget-run-generic 2>&1 > %t.out
5+
// RUN: %fcheck-generic --check-prefixes=CHECK < %t.out
6+
// clang-format on
7+
8+
// UNSUPPORTED: aarch64-unknown-linux-gnu
9+
// UNSUPPORTED: aarch64-unknown-linux-gnu-LTO
10+
// UNSUPPORTED: x86_64-pc-linux-gnu
11+
// UNSUPPORTED: x86_64-pc-linux-gnu-LTO
12+
// UNSUPPORTED: s390x-ibm-linux-gnu
13+
// UNSUPPORTED: s390x-ibm-linux-gnu-LTO
14+
15+
#include <omp.h>
16+
17+
int main(void) {
18+
int X;
19+
omp_target_free(&X, 0);
20+
}

0 commit comments

Comments
 (0)