Skip to content

Commit 846e0e5

Browse files
committed
Include length in CString
1 parent a9e6747 commit 846e0e5

5 files changed

Lines changed: 33 additions & 11 deletions

File tree

src/methods.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,10 @@ extern "C"
3535
if (!PyArg_ParseTuple(args, "sssK", &module, &region_name, &file_name, &line_number))
3636
return NULL;
3737

38-
const std::string& region = scorepy::make_region_name(module, region_name);
39-
scorepy::region_begin(region, module, file_name, line_number);
38+
const std::string& region =
39+
scorepy::make_region_name(scorepy::CString(module), scorepy::CString(region_name));
40+
scorepy::region_begin(region, scorepy::CString(module), scorepy::CString(file_name),
41+
line_number);
4042

4143
Py_RETURN_NONE;
4244
}
@@ -52,7 +54,8 @@ extern "C"
5254
if (!PyArg_ParseTuple(args, "ss", &module, &region_name))
5355
return NULL;
5456

55-
const std::string& region = scorepy::make_region_name(module, region_name);
57+
const std::string& region =
58+
scorepy::make_region_name(scorepy::CString(module), scorepy::CString(region_name));
5659
scorepy::region_end(region);
5760

5861
Py_RETURN_NONE;

src/scorepy/cInstrumenter.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ bool CInstrumenter::on_event(PyFrameObject& frame, int what, PyObject*)
115115
case PyTrace_CALL:
116116
{
117117
const PyCodeObject& code = *frame.f_code;
118-
const CString name = PyUnicode_AsUTF8(code.co_name);
118+
const CString name = get_string_from_python(*code.co_name);
119119
const CString module_name = get_module_name(frame);
120120
if (name != "_unsetprofile" && !module_name.starts_with("scorep"))
121121
{
@@ -129,7 +129,7 @@ bool CInstrumenter::on_event(PyFrameObject& frame, int what, PyObject*)
129129
case PyTrace_RETURN:
130130
{
131131
const PyCodeObject& code = *frame.f_code;
132-
const CString name = PyUnicode_AsUTF8(code.co_name);
132+
const CString name = get_string_from_python(*code.co_name);
133133
const CString module_name = get_module_name(frame);
134134
if (name != "_unsetprofile" && !module_name.starts_with("scorep"))
135135
{

src/scorepy/cstring.h

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,21 @@ namespace scorepy
1010
class CString
1111
{
1212
const char* s_;
13+
size_t len_;
1314

1415
public:
15-
CString(const char* s) : s_(s)
16+
template <size_t N>
17+
constexpr CString(const char (&s)[N]) : s_(s), len_(N - 1u)
18+
{
19+
static_assert(N > 0, "Cannot handle empty char array");
20+
}
21+
22+
explicit CString(const char* s, size_t len) : s_(s), len_(len)
23+
{
24+
assert(s_);
25+
}
26+
27+
explicit CString(const char* s) : s_(s), len_(std::strlen(s_))
1628
{
1729
assert(s_);
1830
}
@@ -29,12 +41,12 @@ class CString
2941
template <size_t N>
3042
bool starts_with(const char (&prefix)[N]) const
3143
{
32-
return std::strncmp(s_, prefix, N - 1u) == 0;
44+
return (len_ >= N - 1u) && (std::strncmp(s_, prefix, N - 1u) == 0);
3345
}
3446

3547
friend bool operator==(const CString& lhs, const CString& rhs)
3648
{
37-
return std::strcmp(lhs.s_, rhs.s_) == 0;
49+
return (lhs.len_ == rhs.len_) && (std::memcmp(lhs.s_, rhs.s_, rhs.len_) == 0);
3850
}
3951
friend bool operator!=(const CString& lhs, const CString& rhs)
4052
{

src/scorepy/pythonHelpers.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ CString get_module_name(const PyFrameObject& frame)
77
{
88
PyObject* module_name = PyDict_GetItemString(frame.f_globals, "__name__");
99
if (module_name)
10-
return PyUnicode_AsUTF8(module_name);
10+
return get_string_from_python(*module_name);
1111

1212
// this is a NUMPY special situation, see NEP-18, and Score-P issue #63
13-
const CString filename = PyUnicode_AsUTF8(frame.f_code->co_filename);
13+
const CString filename = get_string_from_python(*frame.f_code->co_filename);
1414
if (filename == "<__array_function__ internals>")
1515
{
1616
return "numpy.__array_function__";
@@ -30,6 +30,6 @@ CString get_file_name(const PyFrameObject& frame)
3030
}
3131
static char actual_path[PATH_MAX];
3232
const char* full_file_name = realpath(PyUnicode_AsUTF8(filename), actual_path);
33-
return full_file_name ? full_file_name : "ErrorPath";
33+
return full_file_name ? CString(full_file_name) : CString("ErrorPath");
3434
}
3535
} // namespace scorepy

src/scorepy/pythonHelpers.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,13 @@ auto cast_to_PyFunc(TFunc* func) -> detail::ReplaceArgsToPyObject_t<TFunc>*
7272
return reinterpret_cast<detail::ReplaceArgsToPyObject_t<TFunc>*>(func);
7373
}
7474

75+
inline CString get_string_from_python(PyObject& o)
76+
{
77+
Py_ssize_t len;
78+
const char* s = PyUnicode_AsUTF8AndSize(&o, &len);
79+
return CString(s, len);
80+
}
81+
7582
/// Return the module name the frame belongs to.
7683
/// The pointer is valid for the lifetime of the frame
7784
CString get_module_name(const PyFrameObject& frame);

0 commit comments

Comments
 (0)