blob: ea479d5fd129d211706698722b8edc8f05a9542a (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
|
#pragma once
#include <util/system/sys_alloc.h>
#include <util/system/backtrace.h>
#include "shared_data.h"
class TBackTracingOwner : public NActors::TSharedData::IOwner {
using THeader = NActors::TSharedData::THeader;
using TSelf = TBackTracingOwner;
using IOwner = NActors::TSharedData::IOwner;
static constexpr size_t PrivateHeaderSize = NActors::TSharedData::PrivateHeaderSize;
static constexpr size_t HeaderSize = NActors::TSharedData::HeaderSize;
static constexpr size_t OverheadSize = NActors::TSharedData::OverheadSize;
IOwner* RealOwner = nullptr;
TBackTrace BackTrace;
const char* Info;
public:
static constexpr const char* INFO_FROM_SHARED_DATA = "FROM_SHARED_DATA";
static constexpr const char* INFO_COPIED_STRING = "COPIED_STRING";
static constexpr const char* INFO_ALLOC_UNINITIALIZED = "ALLOC_UNINITIALIZED";
static constexpr const char* INFO_ALLOC_UNINIT_ROOMS = "ALLOC_UNINIT_ROOMS";
static char* Allocate(size_t size, const char* info = nullptr) {
char* raw = reinterpret_cast<char*>(y_allocate(OverheadSize + size));
THeader* header = reinterpret_cast<THeader*>(raw + PrivateHeaderSize);
TSelf* btOwner = new TSelf;
btOwner->BackTrace.Capture();
btOwner->Info = info;
header->RefCount = 1;
header->Owner = btOwner;
char* data = raw + OverheadSize;
return data;
}
static void FakeOwner(const NActors::TSharedData& data, const char* info = nullptr) {
THeader* header = Header(data);
if (header) {
TSelf* btOwner = new TSelf();
btOwner->BackTrace.Capture();
btOwner->Info = info;
if (header->Owner) {
btOwner->RealOwner = header->Owner;
}
header->Owner = btOwner;
}
}
static void UnsafePrintBackTrace(NActors::TSharedData& data) {
THeader* header = Header(data);
if(header->Owner) {
TSelf* owner = static_cast<TSelf*>(header->Owner);
owner->PrintBackTrace();
}
}
void Deallocate(char* data) noexcept override {
if (!RealOwner) {
char* raw = data - OverheadSize;
y_deallocate(raw);
} else {
RealOwner->Deallocate(data);
}
delete this;
}
IOwner* GetRealOwner() const {
return RealOwner;
}
void PrintBackTrace() {
Cerr << "Deallocate TSharedData with info# " << Info << Endl;
BackTrace.PrintTo(Cerr);
}
private:
static Y_FORCE_INLINE THeader* Header(const NActors::TSharedData& d) noexcept {
char* data = const_cast<char*>(d.data());
if (data) {
return reinterpret_cast<THeader*>(data - HeaderSize);
} else {
return nullptr;
}
}
};
|