aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Python/sysmodule.c
diff options
context:
space:
mode:
Diffstat (limited to 'Python/sysmodule.c')
-rw-r--r--Python/sysmodule.c80
1 files changed, 79 insertions, 1 deletions
diff --git a/Python/sysmodule.c b/Python/sysmodule.c
index 7510be538ca..33147f012b6 100644
--- a/Python/sysmodule.c
+++ b/Python/sysmodule.c
@@ -52,6 +52,10 @@ extern const char *PyWin_DLLVersionString;
#include <emscripten.h>
#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
/*[clinic input]
module sys
[clinic start generated code]*/
@@ -2144,7 +2148,7 @@ sys_activate_stack_trampoline_impl(PyObject *module, const char *backend)
if (strcmp(backend, "perf") == 0) {
_PyPerf_Callbacks cur_cb;
_PyPerfTrampoline_GetCallbacks(&cur_cb);
- if (cur_cb.init_state != _Py_perfmap_callbacks.init_state) {
+ if (cur_cb.write_state != _Py_perfmap_callbacks.write_state) {
if (_PyPerfTrampoline_SetCallbacks(&_Py_perfmap_callbacks) < 0 ) {
PyErr_SetString(PyExc_ValueError, "can't activate perf trampoline");
return NULL;
@@ -2240,6 +2244,80 @@ sys__getframemodulename_impl(PyObject *module, int depth)
}
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+static PerfMapState perf_map_state;
+
+PyAPI_FUNC(int) PyUnstable_PerfMapState_Init(void) {
+#ifndef MS_WINDOWS
+ char filename[100];
+ pid_t pid = getpid();
+ // Use nofollow flag to prevent symlink attacks.
+ int flags = O_WRONLY | O_CREAT | O_APPEND | O_NOFOLLOW | O_CLOEXEC;
+ snprintf(filename, sizeof(filename) - 1, "/tmp/perf-%jd.map",
+ (intmax_t)pid);
+ int fd = open(filename, flags, 0600);
+ if (fd == -1) {
+ return -1;
+ }
+ else{
+ perf_map_state.perf_map = fdopen(fd, "a");
+ if (perf_map_state.perf_map == NULL) {
+ close(fd);
+ return -1;
+ }
+ }
+ perf_map_state.map_lock = PyThread_allocate_lock();
+ if (perf_map_state.map_lock == NULL) {
+ fclose(perf_map_state.perf_map);
+ return -2;
+ }
+#endif
+ return 0;
+}
+
+PyAPI_FUNC(int) PyUnstable_WritePerfMapEntry(
+ const void *code_addr,
+ unsigned int code_size,
+ const char *entry_name
+) {
+#ifndef MS_WINDOWS
+ if (perf_map_state.perf_map == NULL) {
+ int ret = PyUnstable_PerfMapState_Init();
+ if(ret != 0){
+ return ret;
+ }
+ }
+ PyThread_acquire_lock(perf_map_state.map_lock, 1);
+ fprintf(perf_map_state.perf_map, "%" PRIxPTR " %x %s\n", (uintptr_t) code_addr, code_size, entry_name);
+ fflush(perf_map_state.perf_map);
+ PyThread_release_lock(perf_map_state.map_lock);
+#endif
+ return 0;
+}
+
+PyAPI_FUNC(void) PyUnstable_PerfMapState_Fini(void) {
+#ifndef MS_WINDOWS
+ if (perf_map_state.perf_map != NULL) {
+ // close the file
+ PyThread_acquire_lock(perf_map_state.map_lock, 1);
+ fclose(perf_map_state.perf_map);
+ PyThread_release_lock(perf_map_state.map_lock);
+
+ // clean up the lock and state
+ PyThread_free_lock(perf_map_state.map_lock);
+ perf_map_state.perf_map = NULL;
+ }
+#endif
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+
static PyMethodDef sys_methods[] = {
/* Might as well keep this in alphabetic order */
SYS_ADDAUDITHOOK_METHODDEF