-
-
Notifications
You must be signed in to change notification settings - Fork 32.2k
gh-103295: expose API for writing perf map files #103546
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
60 commits
Select commit
Hold shift + click to select a range
f76d2c5
Update osmodule.h
gsallam de6b63e
Update posixmodule.c
gsallam 4f55b2d
Update pycore_ceval_state.h
gsallam 03fccfb
Update perf_trampoline.c
gsallam 78d543a
Update pylifecycle.c
gsallam e8c321d
Update pycore_ceval.h
gsallam 3a97933
Update _testinternalcapi.c
gsallam 94441c4
Create test_perfmaps.py
gsallam a221fd8
Update posixmodule.c
gsallam 392e842
Update osmodule.h
gsallam 4223241
Update osmodule.h
gsallam 804153a
Update osmodule.h
gsallam ce54c6c
Update posixmodule.c
gsallam 6c3f233
📜🤖 Added by blurb_it.
blurb-it[bot] 71db361
Update osmodule.h
gsallam 020c872
Update test_perfmaps.py
gsallam e33b45d
Update ignored.tsv
gsallam 04e9716
Fix trampoline APIs on windows, return int instead of void* from the …
czardoz 4b8cd26
fix restructuredtext literals
czardoz ccc2d5b
add perfmaps docs under utilities
czardoz 71a7578
make "state" a non-required part of trampoline
czardoz 0ede039
make the API no-op on windows, instead of raising errors
czardoz 7356a9b
use PyUnstable as a prefix
gsallam b504e9a
move the implementation of the perf-map api to the sys module
gsallam 99dab1a
Remove the perf-map API from the posixmodule.c
gsallam 6b95cbc
Update perfmaps.rst to reflect the PyUnstable prefix
gsallam d0ef0a1
Update perf_trampoline.c to use PyUnstable_WritePerfMapEntry
gsallam c5e766b
Update pylifecycle.c to use PyUnstable_PerfMapState_Fini
gsallam b0641a7
expose PyUnstable_PerfMapState_Fini
gsallam c392b24
use assertIn instead of assertEqual and tear down the perf_map_state …
gsallam 262a38b
use malloc instead of fixed buffer size
gsallam a52a25a
Fix perf map entry to have the START and SIZE as hex numbers without 0x
gsallam 0932e30
Add (uintptr_t) casting for the code_addr
gsallam 5aeb74c
update the perf map entry example to be hex without 0x
gsallam b0682e0
Update the doc with the PyUnstable prefix
gsallam db00a03
Merge remote-tracking branch 'upstream/main'
czardoz e581026
change function name to the new one
czardoz e185092
fix tests_perfmaps
gsallam c97137b
Update ignored.tsv
gsallam 344782b
remove extra new line
gsallam 1ff695a
remove extra trailing white space
gsallam 2f13a4e
check perf_map_entry for NULL.
gpshead faa85f5
Merge remote-tracking branch 'upstream/main'
czardoz 50d27e1
update docs
czardoz 717c4e4
remove rst extension from inline doc links
czardoz 428dfc3
fix the free_state function signature
czardoz ca2c0ff
Merge remote-tracking branch 'upstream/main'
czardoz e386ef8
trim extra whitespace
czardoz d245fbf
Return error codes instead of setting exceptions in PyUnstable_PerfMa…
gsallam 2027de6
Add a note that holding the GIL is not required for these APIs
gsallam 0383b80
Remove the init_state call since it is always NULL for the perf backend
gsallam 59f3c15
trim extra whitespaces
gsallam 8bc6150
simplify link to perf map docs from perf profiling
carljm c7a49b4
document return values, other doc tweaks
carljm 125513a
move headers to sysmodule.h
carljm 10630e8
pass through init return value from write-entry
carljm 386dd42
apparently :c:data:`errno` doesn't exist
carljm 6585f32
use PyMem_Raw* instead of malloc/free
carljm ea5965a
Merge branch 'main' into gsallam/main
carljm e6be2a7
fix PyMem_Free to PyMem_RawFree
carljm File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
carljm marked this conversation as resolved.
Show resolved
Hide resolved
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
.. highlight:: c | ||
|
||
.. _perfmaps: | ||
|
||
Support for Perf Maps | ||
---------------------- | ||
|
||
On supported platforms (as of this writing, only Linux), the runtime can take | ||
advantage of *perf map files* to make Python functions visible to an external | ||
profiling tool (such as `perf <https://perf.wiki.kernel.org/index.php/Main_Page>`_). | ||
A running process may create a file in the ``/tmp`` directory, which contains entries | ||
that can map a section of executable code to a name. This interface is described in the | ||
`documentation of the Linux Perf tool <https://git.kernel.org/pub/scm/linux/ | ||
kernel/git/torvalds/linux.git/tree/tools/perf/Documentation/jit-interface.txt>`_. | ||
|
||
In Python, these helper APIs can be used by libraries and features that rely | ||
on generating machine code on the fly. | ||
|
||
Note that holding the Global Interpreter Lock (GIL) is not required for these APIs. | ||
|
||
.. c:function:: int PyUnstable_PerfMapState_Init(void) | ||
Open the ``/tmp/perf-$pid.map`` file, unless it's already opened, and create | ||
a lock to ensure thread-safe writes to the file (provided the writes are | ||
done through :c:func:`PyUnstable_WritePerfMapEntry`). Normally, there's no need | ||
to call this explicitly; just use :c:func:`PyUnstable_WritePerfMapEntry` | ||
and it will initialize the state on first call. | ||
|
||
Returns ``0`` on success, ``-1`` on failure to create/open the perf map file, | ||
or ``-2`` on failure to create a lock. Check ``errno`` for more information | ||
about the cause of a failure. | ||
|
||
.. c:function:: int PyUnstable_WritePerfMapEntry(const void *code_addr, unsigned int code_size, const char *entry_name) | ||
Write one single entry to the ``/tmp/perf-$pid.map`` file. This function is | ||
thread safe. Here is what an example entry looks like:: | ||
# address size name | ||
7f3529fcf759 b py::bar:/run/t.py | ||
Will call :c:func:`PyUnstable_PerfMapState_Init` before writing the entry, if | ||
the perf map file is not already opened. Returns ``0`` on success, or the | ||
same error codes as :c:func:`PyUnstable_PerfMapState_Init` on failure. | ||
.. c:function:: void PyUnstable_PerfMapState_Fini(void) | ||
Close the perf map file opened by :c:func:`PyUnstable_PerfMapState_Init`. | ||
This is called by the runtime itself during interpreter shut-down. In | ||
general, there shouldn't be a reason to explicitly call this, except to | ||
handle specific scenarios such as forking. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import os | ||
import sys | ||
import unittest | ||
|
||
from _testinternalcapi import perf_map_state_teardown, write_perf_map_entry | ||
|
||
if sys.platform != 'linux': | ||
raise unittest.SkipTest('Linux only') | ||
|
||
|
||
class TestPerfMapWriting(unittest.TestCase): | ||
def test_write_perf_map_entry(self): | ||
self.assertEqual(write_perf_map_entry(0x1234, 5678, "entry1"), 0) | ||
self.assertEqual(write_perf_map_entry(0x2345, 6789, "entry2"), 0) | ||
with open(f"/tmp/perf-{os.getpid()}.map") as f: | ||
perf_file_contents = f.read() | ||
self.assertIn("1234 162e entry1", perf_file_contents) | ||
self.assertIn("2345 1a85 entry2", perf_file_contents) | ||
perf_map_state_teardown() |
5 changes: 5 additions & 0 deletions
5
Misc/NEWS.d/next/C API/2023-04-14-23-05-52.gh-issue-103295.GRHY1Z.rst
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
Introduced :c:func:`PyUnstable_WritePerfMapEntry`, :c:func:`PyUnstable_PerfMapState_Init` and | ||
:c:func:`PyUnstable_PerfMapState_Fini`. These allow extension modules (JIT compilers in | ||
particular) to write to perf-map files in a thread safe manner. The | ||
:doc:`../howto/perf_profiling` also uses these APIs to write | ||
entries in the perf-map file. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.