Skip to content

Commit 7e12a2c

Browse files
chore(profiling): remove native from echion
1 parent d2fba79 commit 7e12a2c

File tree

8 files changed

+34
-394
lines changed

8 files changed

+34
-394
lines changed

ddtrace/internal/datadog/profiling/stack_v2/echion/echion/config.h

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,6 @@ inline int cpu = 0;
1717
// Set this to false to unwind all threads.
1818
inline bool ignore_non_running_threads = true;
1919

20-
// Native stack sampling
21-
inline int native = 0;
22-
2320
// Maximum number of frames to unwind
2421
inline unsigned int max_frames = 2048;
2522

@@ -59,24 +56,6 @@ static PyObject* set_cpu(PyObject* Py_UNUSED(m), PyObject* args)
5956
Py_RETURN_NONE;
6057
}
6158

62-
// ----------------------------------------------------------------------------
63-
static PyObject* set_native(PyObject* Py_UNUSED(m), PyObject* Py_UNUSED(args))
64-
{
65-
#ifndef UNWIND_NATIVE_DISABLE
66-
int new_native;
67-
if (!PyArg_ParseTuple(args, "p", &new_native))
68-
return NULL;
69-
70-
native = new_native;
71-
#else
72-
PyErr_SetString(PyExc_RuntimeError,
73-
"Native profiling is disabled, please re-build/install echion without "
74-
"UNWIND_NATIVE_DISABLE env var/preprocessor flag");
75-
return NULL;
76-
#endif // UNWIND_NATIVE_DISABLE
77-
Py_RETURN_NONE;
78-
}
79-
8059
// ----------------------------------------------------------------------------
8160
static PyObject* set_max_frames(PyObject* Py_UNUSED(m), PyObject* args)
8261
{

ddtrace/internal/datadog/profiling/stack_v2/echion/echion/frame.h

Lines changed: 19 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
#if PY_VERSION_HEX >= 0x030d0000
1818
#define Py_BUILD_CORE
1919
#include <internal/pycore_code.h>
20-
#endif // PY_VERSION_HEX >= 0x030d0000
20+
#endif // PY_VERSION_HEX >= 0x030d0000
2121
#if PY_VERSION_HEX >= 0x030b0000
2222
#define Py_BUILD_CORE
2323
#include <internal/pycore_frame.h>
@@ -28,24 +28,18 @@
2828
#include <cstring>
2929
#include <functional>
3030

31-
#ifndef UNWIND_NATIVE_DISABLE
32-
#include <cxxabi.h>
33-
#define UNW_LOCAL_ONLY
34-
#include <libunwind.h>
35-
#endif // UNWIND_NATIVE_DISABLE
36-
3731
#include <echion/cache.h>
3832
#include <echion/mojo.h>
3933
#if PY_VERSION_HEX >= 0x030b0000
4034
#include <echion/stack_chunk.h>
41-
#endif // PY_VERSION_HEX >= 0x030b0000
35+
#endif // PY_VERSION_HEX >= 0x030b0000
4236
#include <echion/strings.h>
4337
#include <echion/vm.h>
4438

4539
// ----------------------------------------------------------------------------
4640
class Frame
4741
{
48-
public:
42+
public:
4943
using Ref = std::reference_wrapper<Frame>;
5044
using Ptr = std::unique_ptr<Frame>;
5145
using Key = uintptr_t;
@@ -68,31 +62,28 @@ class Frame
6862
#endif
6963

7064
// ------------------------------------------------------------------------
71-
Frame(StringTable::Key filename, StringTable::Key name) : filename(filename), name(name) {}
72-
Frame(StringTable::Key name) : name(name) {};
65+
Frame(StringTable::Key filename, StringTable::Key name)
66+
: filename(filename)
67+
, name(name)
68+
{
69+
}
70+
Frame(StringTable::Key name)
71+
: name(name) {};
7372
Frame(PyObject* frame);
7473
[[nodiscard]] static Result<Frame::Ptr> create(PyCodeObject* code, int lasti);
75-
#ifndef UNWIND_NATIVE_DISABLE
76-
[[nodiscard]] static Result<Frame::Ptr> create(unw_cursor_t& cursor, unw_word_t pc);
77-
#endif // UNWIND_NATIVE_DISABLE
7874

7975
#if PY_VERSION_HEX >= 0x030b0000
80-
[[nodiscard]] static Result<std::reference_wrapper<Frame>> read(
81-
_PyInterpreterFrame* frame_addr, _PyInterpreterFrame** prev_addr);
76+
[[nodiscard]] static Result<std::reference_wrapper<Frame>> read(_PyInterpreterFrame* frame_addr,
77+
_PyInterpreterFrame** prev_addr);
8278
#else
83-
[[nodiscard]] static Result<std::reference_wrapper<Frame>> read(PyObject* frame_addr,
84-
PyObject** prev_addr);
79+
[[nodiscard]] static Result<std::reference_wrapper<Frame>> read(PyObject* frame_addr, PyObject** prev_addr);
8580
#endif
8681

87-
[[nodiscard]] static Result<std::reference_wrapper<Frame>> get(PyCodeObject* code_addr,
88-
int lasti);
82+
[[nodiscard]] static Result<std::reference_wrapper<Frame>> get(PyCodeObject* code_addr, int lasti);
8983
static Frame& get(PyObject* frame);
90-
#ifndef UNWIND_NATIVE_DISABLE
91-
[[nodiscard]] static Result<std::reference_wrapper<Frame>> get(unw_cursor_t& cursor);
92-
#endif // UNWIND_NATIVE_DISABLE
9384
static Frame& get(StringTable::Key name);
9485

95-
private:
86+
private:
9687
[[nodiscard]] Result<void> inline infer_location(PyCodeObject* code, int lasti);
9788
static inline Key key(PyCodeObject* code, int lasti);
9889
static inline Key key(PyObject* frame);
@@ -105,5 +96,7 @@ inline auto C_FRAME = Frame(StringTable::C_FRAME);
10596
// We make this a raw pointer to prevent its destruction on exit, since we
10697
// control the lifetime of the cache.
10798
inline LRUCache<uintptr_t, Frame>* frame_cache = nullptr;
108-
void init_frame_cache(size_t capacity);
109-
void reset_frame_cache();
99+
void
100+
init_frame_cache(size_t capacity);
101+
void
102+
reset_frame_cache();

ddtrace/internal/datadog/profiling/stack_v2/echion/echion/signals.h

Lines changed: 0 additions & 46 deletions
This file was deleted.

ddtrace/internal/datadog/profiling/stack_v2/echion/echion/stacks.h

Lines changed: 0 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,6 @@
1212
#include <unordered_map>
1313
#include <unordered_set>
1414

15-
#ifndef UNWIND_NATIVE_DISABLE
16-
#define UNW_LOCAL_ONLY
17-
#include <libunwind.h>
18-
#endif // UNWIND_NATIVE_DISABLE
19-
2015
#include <echion/config.h>
2116
#include <echion/frame.h>
2217
#include <echion/mojo.h>
@@ -69,34 +64,8 @@ class FrameStack : public std::deque<Frame::Ref>
6964
// ----------------------------------------------------------------------------
7065

7166
inline FrameStack python_stack;
72-
inline FrameStack native_stack;
7367
inline FrameStack interleaved_stack;
7468

75-
// ----------------------------------------------------------------------------
76-
#ifndef UNWIND_NATIVE_DISABLE
77-
inline void unwind_native_stack()
78-
{
79-
unw_cursor_t cursor;
80-
unw_context_t context;
81-
82-
unw_getcontext(&context);
83-
unw_init_local(&cursor, &context);
84-
85-
native_stack.clear();
86-
87-
while (unw_step(&cursor) > 0 && native_stack.size() < max_frames)
88-
{
89-
auto maybe_frame = Frame::get(cursor);
90-
if (!maybe_frame)
91-
{
92-
break;
93-
}
94-
95-
native_stack.push_back(*maybe_frame);
96-
}
97-
}
98-
#endif // UNWIND_NATIVE_DISABLE
99-
10069
// ----------------------------------------------------------------------------
10170
static size_t unwind_frame(PyObject* frame_addr, FrameStack& stack)
10271
{
@@ -246,75 +215,6 @@ static void unwind_python_stack(PyThreadState* tstate)
246215
unwind_python_stack(tstate, python_stack);
247216
}
248217

249-
// ----------------------------------------------------------------------------
250-
static Result<void> interleave_stacks(FrameStack& cur_python_stack)
251-
{
252-
interleaved_stack.clear();
253-
254-
auto p = cur_python_stack.rbegin();
255-
// The last two frames are usually the signal trampoline and the signal
256-
// handler. We skip them.
257-
for (auto n = native_stack.rbegin(); n != native_stack.rend() - 2; ++n)
258-
{
259-
auto native_frame = *n;
260-
261-
auto maybe_name = string_table.lookup(native_frame.get().name);
262-
if (!maybe_name)
263-
{
264-
return ErrorKind::LookupError;
265-
}
266-
267-
const auto& name = maybe_name->get();
268-
if (name.find("PyEval_EvalFrameDefault") != std::string::npos)
269-
{
270-
if (p == cur_python_stack.rend())
271-
{
272-
// We expected a Python frame but we found none, so we report
273-
// the native frame instead.
274-
std::cerr << "Expected Python frame(s), found none!" << std::endl;
275-
interleaved_stack.push_front(native_frame);
276-
}
277-
else
278-
{
279-
// We skip the PyEval_EvalFrameDefault frame because it is the
280-
// function that calls the Python code.
281-
#if PY_VERSION_HEX >= 0x030b0000
282-
int cframe_count = 0;
283-
while (p != cur_python_stack.rend())
284-
{
285-
// The Python stack will start with an entry frame at the top.
286-
// We stop popping at the next entry frame.
287-
cframe_count += (*p).get().is_entry;
288-
if (cframe_count >= 2)
289-
break;
290-
291-
interleaved_stack.push_front(*p++);
292-
}
293-
#else
294-
interleaved_stack.push_front(*p++);
295-
#endif
296-
}
297-
}
298-
else
299-
interleaved_stack.push_front(native_frame);
300-
}
301-
302-
if (p != cur_python_stack.rend())
303-
{
304-
std::cerr << "Python stack not empty after interleaving!" << std::endl;
305-
while (p != python_stack.rend())
306-
interleaved_stack.push_front(*p++);
307-
}
308-
309-
return Result<void>::ok();
310-
}
311-
312-
// ----------------------------------------------------------------------------
313-
static Result<void> interleave_stacks()
314-
{
315-
return interleave_stacks(python_stack);
316-
}
317-
318218
// ----------------------------------------------------------------------------
319219
class StackInfo
320220
{

ddtrace/internal/datadog/profiling/stack_v2/echion/echion/strings.h

Lines changed: 0 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,6 @@
1111
#include <cstdint>
1212
#include <string>
1313

14-
#ifndef UNWIND_NATIVE_DISABLE
15-
#include <cxxabi.h>
16-
#define UNW_LOCAL_ONLY
17-
#include <libunwind.h>
18-
#endif // UNWIND_NATIVE_DISABLE
19-
20-
2114
#include <echion/long.h>
2215
#include <echion/render.h>
2316
#include <echion/vm.h>
@@ -153,66 +146,6 @@ class StringTable : public std::unordered_map<uintptr_t, std::string>
153146
return k;
154147
};
155148

156-
#ifndef UNWIND_NATIVE_DISABLE
157-
// Native filename by program counter
158-
[[nodiscard]] inline Key key(unw_word_t pc)
159-
{
160-
const std::lock_guard<std::mutex> lock(table_lock);
161-
162-
auto k = static_cast<Key>(pc);
163-
164-
if (this->find(k) == this->end())
165-
{
166-
char buffer[32] = {0};
167-
std::snprintf(buffer, 32, "native@%p", reinterpret_cast<void*>(k));
168-
this->emplace(k, buffer);
169-
Renderer::get().string(k, buffer);
170-
}
171-
172-
return k;
173-
}
174-
175-
// Native scope name by unwinding cursor
176-
[[nodiscard]] inline Result<Key> key(unw_cursor_t& cursor)
177-
{
178-
const std::lock_guard<std::mutex> lock(table_lock);
179-
180-
unw_proc_info_t pi;
181-
if ((unw_get_proc_info(&cursor, &pi)))
182-
return ErrorKind::UnwindError;
183-
184-
auto k = reinterpret_cast<Key>(pi.start_ip);
185-
186-
if (this->find(k) == this->end())
187-
{
188-
unw_word_t offset; // Ignored. All the information is in the PC anyway.
189-
char sym[256];
190-
if (unw_get_proc_name(&cursor, sym, sizeof(sym), &offset))
191-
return ErrorKind::UnwindError;
192-
193-
char* name = sym;
194-
195-
// Try to demangle C++ names
196-
char* demangled = NULL;
197-
if (name[0] == '_' && name[1] == 'Z')
198-
{
199-
int status;
200-
demangled = abi::__cxa_demangle(name, NULL, NULL, &status);
201-
if (status == 0)
202-
name = demangled;
203-
}
204-
205-
this->emplace(k, name);
206-
Renderer::get().string(k, name);
207-
208-
if (demangled)
209-
std::free(demangled);
210-
}
211-
212-
return Result<Key>(k);
213-
}
214-
#endif // UNWIND_NATIVE_DISABLE
215-
216149
[[nodiscard]] inline Result<std::reference_wrapper<std::string>> lookup(Key key)
217150
{
218151
const std::lock_guard<std::mutex> lock(table_lock);

0 commit comments

Comments
 (0)