Skip to content

Commit 2e932e0

Browse files
committed
Add exception sanitizer layer
Add basic exception sanitizer layer that will call std::abort if an exception is thrown.
1 parent 0112320 commit 2e932e0

File tree

7 files changed

+7583
-0
lines changed

7 files changed

+7583
-0
lines changed

scripts/generate_code.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,30 @@ def _mako_print_hpp(path, namespace, tags, version, revision, specs, meta):
330330
specs=specs,
331331
meta=meta)
332332

333+
"""
334+
generates c/c++ files from the specification documents
335+
"""
336+
def _mako_exception_sanitizer_layer_cpp(path, namespace, tags, version, specs, meta):
337+
dstpath = os.path.join(path, "exception_sanitizer")
338+
os.makedirs(dstpath, exist_ok=True)
339+
340+
template = "exceptionddi.cpp.mako"
341+
fin = os.path.join(templates_dir, template)
342+
343+
name = "%s_exceptionddi"%(namespace)
344+
filename = "%s.cpp"%(name)
345+
fout = os.path.join(dstpath, filename)
346+
347+
print("Generating %s..."%fout)
348+
return util.makoWrite(
349+
fin, fout,
350+
name=name,
351+
ver=version,
352+
namespace=namespace,
353+
tags=tags,
354+
specs=specs,
355+
meta=meta)
356+
333357
"""
334358
Entry-point:
335359
generates tools code
@@ -468,6 +492,9 @@ def generate_layers(path, section, namespace, tags, version, specs, meta):
468492
loc += _mako_tracing_layer_cpp(layer_dstpath, namespace, tags, version, specs, meta)
469493
print("TRACING Generated %s lines of code.\n"%loc)
470494

495+
loc += _mako_exception_sanitizer_layer_cpp(layer_dstpath, namespace, tags, version, specs, meta)
496+
print("TRACING Generated %s lines of code.\n"%loc)
497+
471498
"""
472499
Entry-point:
473500
generates common utilities for unified_runtime
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
<%!
2+
import re
3+
from templates import helper as th
4+
%><%
5+
n=namespace
6+
N=n.upper()
7+
8+
x=tags['$x']
9+
X=x.upper()
10+
11+
handle_create_get_retain_release_funcs=th.get_handle_create_get_retain_release_functions(specs, n, tags)
12+
%>/*
13+
*
14+
* Copyright (C) 2023-2024 Intel Corporation
15+
*
16+
* Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM Exceptions.
17+
* See LICENSE.TXT
18+
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
19+
*
20+
* @file ${name}.cpp
21+
*
22+
*/
23+
#include "${x}_exception_sanitizer_layer.hpp"
24+
25+
namespace ur_exception_sanitizer_layer
26+
{
27+
%for obj in th.get_adapter_functions(specs):
28+
<%
29+
func_name=th.make_func_name(n, tags, obj)
30+
31+
param_checks=th.make_param_checks(n, tags, obj, meta=meta).items()
32+
first_errors = [X + "_RESULT_ERROR_INVALID_NULL_POINTER", X + "_RESULT_ERROR_INVALID_NULL_HANDLE"]
33+
sorted_param_checks = sorted(param_checks, key=lambda pair: False if pair[0] in first_errors else True)
34+
35+
tracked_params = list(filter(lambda p: any(th.subt(n, tags, p['type']) in [hf['handle'], hf['handle'] + "*"] for hf in handle_create_get_retain_release_funcs), obj['params']))
36+
%>
37+
///////////////////////////////////////////////////////////////////////////////
38+
/// @brief Intercept function for ${th.make_func_name(n, tags, obj)}
39+
%if 'condition' in obj:
40+
#if ${th.subt(n, tags, obj['condition'])}
41+
%endif
42+
__${x}dlllocal ${x}_result_t ${X}_APICALL
43+
${func_name}(
44+
%for line in th.make_param_lines(n, tags, obj):
45+
${line}
46+
%endfor
47+
)
48+
{${th.get_initial_null_set(obj)}
49+
auto ${th.make_pfn_name(n, tags, obj)} = getContext()->${n}DdiTable.${th.get_table_name(n, tags, obj)}.${th.make_pfn_name(n, tags, obj)};
50+
51+
if( nullptr == ${th.make_pfn_name(n, tags, obj)} ) {
52+
return ${X}_RESULT_ERROR_UNINITIALIZED;
53+
}
54+
55+
${x}_result_t result = UR_RESULT_SUCCESS;
56+
try {
57+
result = ${th.make_pfn_name(n, tags, obj)}( ${", ".join(th.make_param_lines(n, tags, obj, format=["name"]))} );
58+
} catch (...) {
59+
std::cerr << "Exception caught from adapter layer in " << __func__ << " aborting\n";
60+
}
61+
62+
return result;
63+
}
64+
%if 'condition' in obj:
65+
#endif // ${th.subt(n, tags, obj['condition'])}
66+
%endif
67+
68+
%endfor
69+
%for tbl in th.get_pfntables(specs, meta, n, tags):
70+
///////////////////////////////////////////////////////////////////////////////
71+
/// @brief Exported function for filling application's ${tbl['name']} table
72+
/// with current process' addresses
73+
///
74+
/// @returns
75+
/// - ::${X}_RESULT_SUCCESS
76+
/// - ::${X}_RESULT_ERROR_INVALID_NULL_POINTER
77+
/// - ::${X}_RESULT_ERROR_UNSUPPORTED_VERSION
78+
${X}_DLLEXPORT ${x}_result_t ${X}_APICALL
79+
${tbl['export']['name']}(
80+
%for line in th.make_param_lines(n, tags, tbl['export']):
81+
${line}
82+
%endfor
83+
)
84+
{
85+
auto& dditable = ur_exception_sanitizer_layer::getContext()->${n}DdiTable.${tbl['name']};
86+
87+
if( nullptr == pDdiTable )
88+
return ${X}_RESULT_ERROR_INVALID_NULL_POINTER;
89+
90+
if (UR_MAJOR_VERSION(ur_exception_sanitizer_layer::getContext()->version) != UR_MAJOR_VERSION(version) ||
91+
UR_MINOR_VERSION(ur_exception_sanitizer_layer::getContext()->version) > UR_MINOR_VERSION(version))
92+
return ${X}_RESULT_ERROR_UNSUPPORTED_VERSION;
93+
94+
${x}_result_t result = ${X}_RESULT_SUCCESS;
95+
96+
%for obj in tbl['functions']:
97+
%if 'condition' in obj:
98+
#if ${th.subt(n, tags, obj['condition'])}
99+
%endif
100+
dditable.${th.append_ws(th.make_pfn_name(n, tags, obj), 43)} = pDdiTable->${th.make_pfn_name(n, tags, obj)};
101+
pDdiTable->${th.append_ws(th.make_pfn_name(n, tags, obj), 41)} = ur_exception_sanitizer_layer::${th.make_func_name(n, tags, obj)};
102+
%if 'condition' in obj:
103+
#else
104+
dditable.${th.append_ws(th.make_pfn_name(n, tags, obj), 43)} = nullptr;
105+
pDdiTable->${th.append_ws(th.make_pfn_name(n, tags, obj), 41)} = nullptr;
106+
#endif
107+
%endif
108+
109+
%endfor
110+
return result;
111+
}
112+
113+
%endfor
114+
${x}_result_t
115+
context_t::init(ur_dditable_t *dditable,
116+
const std::set<std::string> &enabledLayerNames,
117+
codeloc_data) {
118+
${x}_result_t result = ${X}_RESULT_SUCCESS;
119+
120+
return result;
121+
}
122+
123+
${x}_result_t context_t::tearDown() {
124+
return ${X}_RESULT_SUCCESS;
125+
}
126+
127+
} // namespace ur_exception_sanitizer_layer

source/loader/CMakeLists.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,15 @@ if(UR_ENABLE_SANITIZER)
195195
endif()
196196
endif()
197197

198+
if(UR_ENABLE_EXCEPTION_SANITIZER)
199+
target_sources(ur_loader
200+
PRIVATE
201+
${CMAKE_CURRENT_SOURCE_DIR}/layers/exception_sanitizer/ur_exception_sanitizer_layer.cpp
202+
${CMAKE_CURRENT_SOURCE_DIR}/layers/exception_sanitizer/ur_exception_sanitizer_layer.hpp
203+
${CMAKE_CURRENT_SOURCE_DIR}/layers/exception_sanitizer/ur_exceptionddi.cpp
204+
)
205+
endif()
206+
198207
target_include_directories(ur_loader PRIVATE
199208
"${CMAKE_CURRENT_SOURCE_DIR}/layers/sanitizer"
200209
"${CMAKE_CURRENT_SOURCE_DIR}/../"
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/*
2+
*
3+
* Copyright (C) 2023 Corporation
4+
*
5+
* Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM Exceptions.
6+
* See LICENSE.TXT
7+
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8+
*
9+
* @file ur_exception_sanitizer_layer.h
10+
*
11+
*/
12+
13+
#include "ur_exception_sanitizer_layer.hpp"
14+
15+
namespace ur_exception_sanitizer_layer {
16+
17+
context_t *getContext() { return context_t::get_direct(); }
18+
19+
} // namespace ur_exception_sanitizer_layer
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
*
3+
* Copyright (C) 2023 Corporation
4+
*
5+
* Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM Exceptions.
6+
* See LICENSE.TXT
7+
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8+
*
9+
* @file ur_exception_sanitizer_layer.h
10+
*
11+
*/
12+
13+
#ifndef UR_EXCEPTION_SANITIZER_LAYER_H
14+
#define UR_EXCEPTION_SANITIZER_LAYER_H 1
15+
16+
#include "ur_ddi.h"
17+
#include "ur_proxy_layer.hpp"
18+
#include "ur_util.hpp"
19+
20+
#define EXCEPTION_SANITIZER_COMP_NAME "exception sanitizer layer"
21+
22+
namespace ur_exception_sanitizer_layer {
23+
24+
///////////////////////////////////////////////////////////////////////////////
25+
class __urdlllocal context_t : public proxy_layer_context_t,
26+
public AtomicSingleton<context_t> {
27+
public:
28+
ur_dditable_t urDdiTable = {};
29+
codeloc_data codelocData;
30+
31+
context_t() = default;
32+
~context_t() = default;
33+
34+
ur_result_t init(ur_dditable_t *dditable,
35+
const std::set<std::string> &enabledLayerNames,
36+
codeloc_data codelocData) override;
37+
ur_result_t tearDown() override { return UR_RESULT_SUCCESS; }
38+
39+
private:
40+
inline static const std::string name = "UR_LAYER_EXCEPTION_SANITIZER";
41+
};
42+
43+
context_t *getContext();
44+
45+
} // namespace ur_exception_sanitizer_layer
46+
47+
#endif /* UR_EXCEPTION_SANITIZER_LAYER_H */

0 commit comments

Comments
 (0)