Skip to content

Commit 70e11e2

Browse files
authored
Annotate region exits, of regions that never occure before (#64)
Instead of throwing an exception for regions that are exited, but haven't been seen before, these regions are added as `error_region` to the trace. An error message is printed, stating, that there was an error, and that details might be found in the trace or profile.
1 parent 1c7bf2d commit 70e11e2

3 files changed

Lines changed: 81 additions & 5 deletions

File tree

src/scorep.cpp

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,44 @@ void region_begin(const std::string& region_name, std::string module, std::strin
3131
SCOREP_User_RegionInit(&handle.value, NULL, &SCOREP_User_LastFileHandle,
3232
region_name.c_str(), SCOREP_USER_REGION_TYPE_FUNCTION,
3333
file_name.c_str(), line_number);
34-
SCOREP_User_RegionSetGroup(handle.value, std::string(module,0,module.find('.')).c_str());
34+
SCOREP_User_RegionSetGroup(handle.value, std::string(module, 0, module.find('.')).c_str());
3535
}
3636
SCOREP_User_RegionEnter(handle.value);
3737
}
3838

3939
void region_end(const std::string& region_name)
4040
{
41-
auto& handle = regions.at(region_name);
42-
SCOREP_User_RegionEnd(handle.value);
41+
try
42+
{
43+
auto& handle = regions.at(region_name);
44+
SCOREP_User_RegionEnd(handle.value);
45+
}
46+
catch (std::out_of_range& e)
47+
{
48+
static region_handle error_region;
49+
static SCOREP_User_ParameterHandle scorep_param = SCOREP_USER_INVALID_PARAMETER;
50+
static bool error_printed = false;
51+
52+
if (error_region.value == SCOREP_USER_INVALID_REGION)
53+
{
54+
SCOREP_User_RegionInit(&error_region.value, NULL, &SCOREP_User_LastFileHandle,
55+
"error_region", SCOREP_USER_REGION_TYPE_FUNCTION, "scorep.cpp",
56+
0);
57+
SCOREP_User_RegionSetGroup(error_region.value, "error");
58+
}
59+
SCOREP_User_RegionEnter(error_region.value);
60+
SCOREP_User_ParameterString(&scorep_param, "leave-region", region_name.c_str());
61+
SCOREP_User_RegionEnd(error_region.value);
62+
63+
if (!error_printed)
64+
{
65+
std::cerr << "SCOREP_BINDING_PYTHON ERROR: There was a region exit without an enter!\n"
66+
<< "SCOREP_BINDING_PYTHON ERROR: For details look for \"error_region\" in "
67+
"the trace or profile."
68+
<< std::endl;
69+
error_printed = true;
70+
}
71+
}
4372
}
4473

4574
void rewind_begin(std::string region_name, std::string file_name, std::uint64_t line_number)

test/test.py

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,6 @@ def test_instrumentation(self):
224224
self.assertRegex(std_out,
225225
'LEAVE[ ]*[0-9 ]*[0-9 ]*Region: "__main__:foo"')
226226

227-
228227
def test_user_instrumentation(self):
229228
env = self.env
230229
env["SCOREP_EXPERIMENT_DIRECTORY"] += "/test_user_instrumentation"
@@ -253,6 +252,45 @@ def test_user_instrumentation(self):
253252
self.assertRegex(std_out,
254253
'LEAVE[ ]*[0-9 ]*[0-9 ]*Region: "__main__:foo"')
255254

255+
def test_error_region(self):
256+
env = self.env
257+
env["SCOREP_EXPERIMENT_DIRECTORY"] += "/test_error_region"
258+
trace_path = env["SCOREP_EXPERIMENT_DIRECTORY"] + "/traces.otf2"
259+
260+
out = call([self.python,
261+
"-m",
262+
"scorep",
263+
"--nocompiler",
264+
"--noinstrumenter",
265+
"test_error_region.py"],
266+
env=env)
267+
std_out = out[1]
268+
std_err = out[2]
269+
270+
self.assertEqual(
271+
std_err,
272+
"SCOREP_BINDING_PYTHON ERROR: There was a region exit without an enter!\n" +
273+
"SCOREP_BINDING_PYTHON ERROR: For details look for \"error_region\" in the trace or profile.\n")
274+
self.assertEqual(std_out, "")
275+
276+
out = call(["otf2-print", trace_path])
277+
std_out = out[1]
278+
std_err = out[2]
279+
280+
self.assertEqual(std_err, "")
281+
self.assertRegex(std_out,
282+
'ENTER[ ]*[0-9 ]*[0-9 ]*Region: "error_region"')
283+
self.assertRegex(std_out,
284+
'LEAVE[ ]*[0-9 ]*[0-9 ]*Region: "error_region"')
285+
self.assertRegex(
286+
std_out,
287+
'PARAMETER_STRING[ ]*[0-9 ]*[0-9 ]*Parameter: "leave-region" <[0-9]*>,' +
288+
' Value: "user:test_region"')
289+
self.assertRegex(
290+
std_out,
291+
'PARAMETER_STRING[ ]*[0-9 ]*[0-9 ]*Parameter: "leave-region" <[0-9]*>,' +
292+
' Value: "user:test_region_2"')
293+
256294
@unittest.skipIf(len(pkgutil.extend_path([], "mpi4py")) == 0 or
257295
len(pkgutil.extend_path([], "numpy")) == 0,
258296
"no mpi4py present")
@@ -358,7 +396,7 @@ def test_numpy_dot(self):
358396

359397

360398
def tearDown(self):
361-
#pass
399+
# pass
362400
shutil.rmtree(
363401
self.env["SCOREP_EXPERIMENT_DIRECTORY"],
364402
ignore_errors=True)

test/test_error_region.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import scorep.user
2+
3+
4+
def foo():
5+
scorep.user.region_end("test_region")
6+
scorep.user.region_end("test_region_2")
7+
8+
9+
foo()

0 commit comments

Comments
 (0)