Skip to content

Commit 1b3c5ab

Browse files
authored
Merge pull request #603 from igchor/coverity_fixes
[ur] fix 'uncaught exception' error from coverity
2 parents 50193da + 40e31a8 commit 1b3c5ab

File tree

3 files changed

+96
-109
lines changed

3 files changed

+96
-109
lines changed

source/common/uma_helpers.hpp

Lines changed: 74 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -31,69 +31,68 @@ using provider_unique_handle_t =
3131
std::unique_ptr<uma_memory_provider_t,
3232
std::function<void(uma_memory_provider_handle_t)>>;
3333

34+
#define UMA_ASSIGN_OP(ops, type, func, default_return) \
35+
ops.func = [](void *obj, auto... args) { \
36+
try { \
37+
return reinterpret_cast<type *>(obj)->func(args...); \
38+
} catch (...) { \
39+
return default_return; \
40+
} \
41+
}
42+
43+
#define UMA_ASSIGN_OP_NORETURN(ops, type, func) \
44+
ops.func = [](void *obj, auto... args) { \
45+
try { \
46+
return reinterpret_cast<type *>(obj)->func(args...); \
47+
} catch (...) { \
48+
} \
49+
}
50+
3451
/// @brief creates UMA memory provider based on given T type.
3552
/// T should implement all functions defined by
3653
/// uma_memory_provider_ops_t, except for finalize (it is
3754
/// replaced by dtor). All arguments passed to this function are
38-
/// forwarded to T::initialize(). All functions of T
39-
/// should be noexcept.
55+
/// forwarded to T::initialize().
4056
template <typename T, typename... Args>
4157
auto memoryProviderMakeUnique(Args &&...args) {
4258
uma_memory_provider_ops_t ops;
4359
auto argsTuple = std::make_tuple(std::forward<Args>(args)...);
44-
static_assert(
45-
noexcept(std::declval<T>().initialize(std::forward<Args>(args)...)));
4660

4761
ops.version = UMA_VERSION_CURRENT;
4862
ops.initialize = [](void *params, void **obj) {
4963
auto *tuple = reinterpret_cast<decltype(argsTuple) *>(params);
50-
auto provider = new T;
64+
T *provider;
65+
try {
66+
provider = new T;
67+
} catch (...) {
68+
return UMA_RESULT_ERROR_OUT_OF_HOST_MEMORY;
69+
}
70+
5171
*obj = provider;
52-
auto ret = std::apply(
53-
&T::initialize, std::tuple_cat(std::make_tuple(provider), *tuple));
54-
if (ret != UMA_RESULT_SUCCESS) {
72+
73+
try {
74+
auto ret =
75+
std::apply(&T::initialize,
76+
std::tuple_cat(std::make_tuple(provider), *tuple));
77+
if (ret != UMA_RESULT_SUCCESS) {
78+
delete provider;
79+
}
80+
return ret;
81+
} catch (...) {
5582
delete provider;
83+
return UMA_RESULT_ERROR_UNKNOWN;
5684
}
57-
return ret;
5885
};
5986
ops.finalize = [](void *obj) { delete reinterpret_cast<T *>(obj); };
60-
ops.alloc = [](void *obj, auto... args) {
61-
static_assert(noexcept(reinterpret_cast<T *>(obj)->alloc(args...)));
62-
return reinterpret_cast<T *>(obj)->alloc(args...);
63-
};
64-
ops.free = [](void *obj, auto... args) {
65-
static_assert(noexcept(reinterpret_cast<T *>(obj)->free(args...)));
66-
return reinterpret_cast<T *>(obj)->free(args...);
67-
};
68-
ops.get_last_result = [](void *obj, auto... args) {
69-
static_assert(
70-
noexcept(reinterpret_cast<T *>(obj)->get_last_result(args...)));
71-
return reinterpret_cast<T *>(obj)->get_last_result(args...);
72-
};
73-
ops.get_recommended_page_size = [](void *obj, auto... args) {
74-
static_assert(noexcept(
75-
reinterpret_cast<T *>(obj)->get_recommended_page_size(args...)));
76-
return reinterpret_cast<T *>(obj)->get_recommended_page_size(args...);
77-
};
78-
ops.get_min_page_size = [](void *obj, auto... args) {
79-
static_assert(
80-
noexcept(reinterpret_cast<T *>(obj)->get_min_page_size(args...)));
81-
return reinterpret_cast<T *>(obj)->get_min_page_size(args...);
82-
};
83-
ops.purge_lazy = [](void *obj, auto... args) {
84-
static_assert(
85-
noexcept(reinterpret_cast<T *>(obj)->purge_lazy(args...)));
86-
return reinterpret_cast<T *>(obj)->purge_lazy(args...);
87-
};
88-
ops.purge_force = [](void *obj, auto... args) {
89-
static_assert(
90-
noexcept(reinterpret_cast<T *>(obj)->purge_force(args...)));
91-
return reinterpret_cast<T *>(obj)->purge_force(args...);
92-
};
93-
ops.get_name = [](void *obj, auto... args) {
94-
static_assert(noexcept(reinterpret_cast<T *>(obj)->get_name(args...)));
95-
return reinterpret_cast<T *>(obj)->get_name(args...);
96-
};
87+
88+
UMA_ASSIGN_OP(ops, T, alloc, UMA_RESULT_ERROR_UNKNOWN);
89+
UMA_ASSIGN_OP(ops, T, free, UMA_RESULT_ERROR_UNKNOWN);
90+
UMA_ASSIGN_OP(ops, T, get_last_result, UMA_RESULT_ERROR_UNKNOWN);
91+
UMA_ASSIGN_OP(ops, T, get_recommended_page_size, UMA_RESULT_ERROR_UNKNOWN);
92+
UMA_ASSIGN_OP(ops, T, get_min_page_size, UMA_RESULT_ERROR_UNKNOWN);
93+
UMA_ASSIGN_OP(ops, T, purge_lazy, UMA_RESULT_ERROR_UNKNOWN);
94+
UMA_ASSIGN_OP(ops, T, purge_force, UMA_RESULT_ERROR_UNKNOWN);
95+
UMA_ASSIGN_OP_NORETURN(ops, T, get_name);
9796

9897
uma_memory_provider_handle_t hProvider = nullptr;
9998
auto ret = umaMemoryProviderCreate(&ops, &argsTuple, &hProvider);
@@ -105,63 +104,50 @@ auto memoryProviderMakeUnique(Args &&...args) {
105104
/// T should implement all functions defined by
106105
/// uma_memory_provider_ops_t, except for finalize (it is
107106
/// replaced by dtor). All arguments passed to this function are
108-
/// forwarded to T::initialize(). All functions of T
109-
/// should be noexcept.
107+
/// forwarded to T::initialize().
110108
template <typename T, typename... Args>
111109
auto poolMakeUnique(uma_memory_provider_handle_t *providers,
112110
size_t numProviders, Args &&...args) {
113111
uma_memory_pool_ops_t ops;
114112
auto argsTuple = std::make_tuple(std::forward<Args>(args)...);
115-
static_assert(noexcept(std::declval<T>().initialize(
116-
providers, numProviders, std::forward<Args>(args)...)));
117113

118114
ops.version = UMA_VERSION_CURRENT;
119115
ops.initialize = [](uma_memory_provider_handle_t *providers,
120116
size_t numProviders, void *params, void **obj) {
121117
auto *tuple = reinterpret_cast<decltype(argsTuple) *>(params);
122-
auto pool = new T;
118+
T *pool;
119+
120+
try {
121+
pool = new T;
122+
} catch (...) {
123+
return UMA_RESULT_ERROR_OUT_OF_HOST_MEMORY;
124+
}
125+
123126
*obj = pool;
124-
auto ret = std::apply(
125-
&T::initialize,
126-
std::tuple_cat(std::make_tuple(pool, providers, numProviders),
127-
*tuple));
128-
if (ret != UMA_RESULT_SUCCESS) {
127+
128+
try {
129+
auto ret = std::apply(
130+
&T::initialize,
131+
std::tuple_cat(std::make_tuple(pool, providers, numProviders),
132+
*tuple));
133+
if (ret != UMA_RESULT_SUCCESS) {
134+
delete pool;
135+
}
136+
return ret;
137+
} catch (...) {
129138
delete pool;
139+
return UMA_RESULT_ERROR_UNKNOWN;
130140
}
131-
return ret;
132141
};
133142
ops.finalize = [](void *obj) { delete reinterpret_cast<T *>(obj); };
134-
ops.malloc = [](void *obj, auto... args) {
135-
static_assert(noexcept(reinterpret_cast<T *>(obj)->malloc(args...)));
136-
return reinterpret_cast<T *>(obj)->malloc(args...);
137-
};
138-
ops.calloc = [](void *obj, auto... args) {
139-
static_assert(noexcept(reinterpret_cast<T *>(obj)->calloc(args...)));
140-
return reinterpret_cast<T *>(obj)->calloc(args...);
141-
};
142-
ops.aligned_malloc = [](void *obj, auto... args) {
143-
static_assert(
144-
noexcept(reinterpret_cast<T *>(obj)->aligned_malloc(args...)));
145-
return reinterpret_cast<T *>(obj)->aligned_malloc(args...);
146-
};
147-
ops.realloc = [](void *obj, auto... args) {
148-
static_assert(noexcept(reinterpret_cast<T *>(obj)->realloc(args...)));
149-
return reinterpret_cast<T *>(obj)->realloc(args...);
150-
};
151-
ops.malloc_usable_size = [](void *obj, auto... args) {
152-
static_assert(
153-
noexcept(reinterpret_cast<T *>(obj)->malloc_usable_size(args...)));
154-
return reinterpret_cast<T *>(obj)->malloc_usable_size(args...);
155-
};
156-
ops.free = [](void *obj, auto... args) {
157-
static_assert(noexcept(reinterpret_cast<T *>(obj)->free(args...)));
158-
reinterpret_cast<T *>(obj)->free(args...);
159-
};
160-
ops.get_last_result = [](void *obj, auto... args) {
161-
static_assert(
162-
noexcept(reinterpret_cast<T *>(obj)->get_last_result(args...)));
163-
return reinterpret_cast<T *>(obj)->get_last_result(args...);
164-
};
143+
144+
UMA_ASSIGN_OP(ops, T, malloc, ((void *)nullptr));
145+
UMA_ASSIGN_OP(ops, T, calloc, ((void *)nullptr));
146+
UMA_ASSIGN_OP(ops, T, aligned_malloc, ((void *)nullptr));
147+
UMA_ASSIGN_OP(ops, T, realloc, ((void *)nullptr));
148+
UMA_ASSIGN_OP(ops, T, malloc_usable_size, ((size_t)0));
149+
UMA_ASSIGN_OP_NORETURN(ops, T, free);
150+
UMA_ASSIGN_OP(ops, T, get_last_result, UMA_RESULT_ERROR_UNKNOWN);
165151

166152
uma_memory_pool_handle_t hPool = nullptr;
167153
auto ret = umaPoolCreate(&ops, providers, numProviders, &argsTuple, &hPool);

source/common/uma_pools/disjoint_pool.cpp

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,11 @@ Slab::Slab(Bucket &Bkt)
352352
}
353353

354354
Slab::~Slab() {
355-
unregSlab(*this);
355+
try {
356+
unregSlab(*this);
357+
} catch (std::exception &e) {
358+
std::cout << "DisjointPool: unexpected error: " << e.what() << "\n";
359+
}
356360
memoryProviderFree(bucket.getMemHandle(), MemPtr);
357361
}
358362

@@ -838,7 +842,7 @@ void DisjointPool::AllocImpl::printStats(bool &TitlePrinted,
838842

839843
uma_result_t DisjointPool::initialize(uma_memory_provider_handle_t *providers,
840844
size_t numProviders,
841-
DisjointPoolConfig parameters) noexcept {
845+
DisjointPoolConfig parameters) {
842846
if (numProviders != 1 || !providers[0]) {
843847
return UMA_RESULT_ERROR_INVALID_ARGUMENT;
844848
}
@@ -847,9 +851,8 @@ uma_result_t DisjointPool::initialize(uma_memory_provider_handle_t *providers,
847851
return UMA_RESULT_SUCCESS;
848852
}
849853

850-
void *DisjointPool::malloc(
851-
size_t size) noexcept { // For full-slab allocations indicates
852-
// whether slab is from Pool.
854+
void *DisjointPool::malloc(size_t size) { // For full-slab allocations indicates
855+
// whether slab is from Pool.
853856
bool FromPool;
854857
auto Ptr = impl->allocate(size, FromPool);
855858

@@ -862,19 +865,19 @@ void *DisjointPool::malloc(
862865
return Ptr;
863866
}
864867

865-
void *DisjointPool::calloc(size_t, size_t) noexcept {
868+
void *DisjointPool::calloc(size_t, size_t) {
866869
// Not supported
867870
assert(false);
868871
return NULL;
869872
}
870873

871-
void *DisjointPool::realloc(void *, size_t) noexcept {
874+
void *DisjointPool::realloc(void *, size_t) {
872875
// Not supported
873876
assert(false);
874877
return NULL;
875878
}
876879

877-
void *DisjointPool::aligned_malloc(size_t size, size_t alignment) noexcept {
880+
void *DisjointPool::aligned_malloc(size_t size, size_t alignment) {
878881
bool FromPool;
879882
auto Ptr = impl->allocate(size, alignment, FromPool);
880883

@@ -888,14 +891,14 @@ void *DisjointPool::aligned_malloc(size_t size, size_t alignment) noexcept {
888891
return Ptr;
889892
}
890893

891-
size_t DisjointPool::malloc_usable_size(void *) noexcept {
894+
size_t DisjointPool::malloc_usable_size(void *) {
892895
// Not supported
893896
assert(false);
894897

895898
return 0;
896899
}
897900

898-
void DisjointPool::free(void *ptr) noexcept {
901+
void DisjointPool::free(void *ptr) {
899902
bool ToPool;
900903
impl->deallocate(ptr, ToPool);
901904

@@ -911,8 +914,7 @@ void DisjointPool::free(void *ptr) noexcept {
911914
return;
912915
}
913916

914-
enum uma_result_t
915-
DisjointPool::get_last_result(const char **ppMessage) noexcept {
917+
enum uma_result_t DisjointPool::get_last_result(const char **ppMessage) {
916918
// TODO: implement and return last error, we probably need something like
917919
// https://github.com/oneapi-src/unified-runtime/issues/500 in UMA
918920
return UMA_RESULT_ERROR_UNKNOWN;

source/common/uma_pools/disjoint_pool.hpp

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -61,15 +61,14 @@ class DisjointPool {
6161
using Config = DisjointPoolConfig;
6262

6363
uma_result_t initialize(uma_memory_provider_handle_t *providers,
64-
size_t numProviders,
65-
DisjointPoolConfig parameters) noexcept;
66-
void *malloc(size_t size) noexcept;
67-
void *calloc(size_t, size_t) noexcept;
68-
void *realloc(void *, size_t) noexcept;
69-
void *aligned_malloc(size_t size, size_t alignment) noexcept;
70-
size_t malloc_usable_size(void *) noexcept;
71-
void free(void *ptr) noexcept;
72-
enum uma_result_t get_last_result(const char **ppMessage) noexcept;
64+
size_t numProviders, DisjointPoolConfig parameters);
65+
void *malloc(size_t size);
66+
void *calloc(size_t, size_t);
67+
void *realloc(void *, size_t);
68+
void *aligned_malloc(size_t size, size_t alignment);
69+
size_t malloc_usable_size(void *);
70+
void free(void *ptr);
71+
enum uma_result_t get_last_result(const char **ppMessage);
7372

7473
DisjointPool();
7574
~DisjointPool();

0 commit comments

Comments
 (0)