Skip to content

Commit 30154c2

Browse files
committed
Add basic support for host stack traces
1 parent c8286fb commit 30154c2

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 {
@@ -892,6 +901,8 @@ struct GenericDeviceTy : public DeviceAllocatorTy {
892901
/// Reference to the underlying plugin that created this device.
893902
GenericPluginTy &Plugin;
894903

904+
ProtectedObj<DenseMap<void *, AllocationInfoTy *>> AllocationTraces;
905+
895906
private:
896907
/// Get and set the stack size and heap size for the device. If not used, the
897908
/// plugin can implement the setters as no-op and setting the output
@@ -915,7 +926,6 @@ struct GenericDeviceTy : public DeviceAllocatorTy {
915926

916927
/// Pointer to the memory manager or nullptr if not available.
917928
MemoryManagerTy *MemoryManager;
918-
919929
/// Environment variables defined by the OpenMP standard.
920930
Int32Envar OMP_TeamLimit;
921931
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

@@ -1377,6 +1379,22 @@ Expected<void *> GenericDeviceTy::dataAlloc(int64_t Size, void *HostPtr,
13771379
if (auto Err = PinnedAllocs.registerHostBuffer(Alloc, Alloc, Size))
13781380
return std::move(Err);
13791381

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

@@ -1385,6 +1403,32 @@ Error GenericDeviceTy::dataDelete(void *TgtPtr, TargetAllocTy Kind) {
13851403
if (Plugin.getRecordReplay().isRecordingOrReplaying())
13861404
return Plugin::success();
13871405

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

22962356
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)