Skip to content

Commit 22b3b0a

Browse files
authored
Merge pull request #3953 from RasmusWL/python-more-call-graph-tracing
Approved by tausbn
2 parents d3f1972 + 61998af commit 22b3b0a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+2092
-308
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# As described in https://github.com/psf/black/blob/master/docs/compatible_configs.md#flake8
2+
# and https://black.readthedocs.io/en/stable/the_black_code_style.html#line-length
3+
[flake8]
4+
max-line-length = 88
5+
select = C,E,F,W,B,B950
6+
ignore = E203, E501, W503
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Example DB
2+
cg-trace-example-db/
3+
4+
# Tests artifacts
5+
tests/python-traces/
6+
tests/cg-trace-test-db
7+
8+
# Artifact from building `pip install -e .`
9+
src/cg_trace.egg-info/
10+
11+
projects/
12+
13+
venv/
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[settings]
2+
multi_line_output = 3
3+
include_trailing_comma = True
4+
force_grid_wrap = 0
5+
use_parentheses = True
6+
line_length = 88

python/tools/recorded-call-graph-metrics/README.md

Lines changed: 106 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,113 @@ also known as _call graph tracing_.
44

55
Execute a python program and for each call being made, record the call and callee. This allows us to compare call graph resolution from static analysis with actual data -- that is, can we statically determine the target of each actual call correctly.
66

7-
This is still in the early stages, and currently only supports a very minimal working example (to show that this approach might work).
7+
Using the call graph tracer does incur a heavy toll on the performance. Expect 10x longer to execute the program.
88

9-
The next hurdle is being able to handle multiple calls on the same line, such as
9+
Number of calls recorded vary a little from run to run. I have not been able to pinpoint why.
1010

11-
- `foo(); bar()`
12-
- `foo(bar())`
13-
- `foo().bar()`
11+
## Running against real projects
1412

15-
## How do I give it a spin?
13+
Currently it's possible to gather metrics from traced runs of the standard test suite of a few projects (defined in [projects.json](./projects.json)): `youtube-dl`, `wcwidth`, and `flask`.
1614

17-
Run the `recreate-db.sh` script to create the database `cg-trace-example-db`, which will include the `example/simple.xml` trace from executing the `example/simple.py` code. Then run the queries inside the `ql/` directory.
15+
To run against all projects, use
16+
17+
```bash
18+
$ ./helper.sh all $(./helper.sh projects)
19+
```
20+
21+
To view the results, use
22+
```
23+
$ head -n 100 projects/*/Metrics.txt
24+
```
25+
26+
### Expanding set of projects
27+
28+
It should be fairly straightforward to expand the set of projects. Most projects use `tox` for running their tests against multiple python versions. I didn't look into any kind of integration, but have manually picked out the instructions required to get going.
29+
30+
As an example, compare the [`tox.ini`](https://github.com/pallets/flask/blob/21c3df31de4bc2f838c945bd37d185210d9bab1a/tox.ini) file from flask with the configuration
31+
32+
```json
33+
"flask": {
34+
"repo": "https://github.com/pallets/flask.git",
35+
"sha": "21c3df31de4bc2f838c945bd37d185210d9bab1a",
36+
"module_command": "pytest -c /dev/null tests examples",
37+
"setup": [
38+
"pip install -r requirements/tests.txt",
39+
"pip install -q -e examples/tutorial[test]",
40+
"pip install -q -e examples/javascript[test]"
41+
]
42+
}
43+
```
44+
45+
## Local development
46+
47+
### Setup
48+
49+
1. Ensure you have at least Python 3.7
50+
51+
2. Create virtual environment `python3 -m venv venv` and activate it
52+
53+
3. Install dependencies `pip install -r --upgrade requirements.txt`
54+
55+
4. Install this codebase as an editable package `pip install -e .`
56+
57+
5. Setup your editor. If you're using VS Code, create a new project for this folder, and
58+
use these settings for correct autoformatting of code on save:
59+
```
60+
{
61+
"python.pythonPath": "venv/bin/python",
62+
"python.linting.enabled": true,
63+
"python.linting.flake8Enabled": true,
64+
"python.formatting.provider": "black",
65+
"editor.formatOnSave": true,
66+
"[python]": {
67+
"editor.codeActionsOnSave": {
68+
"source.organizeImports": true
69+
}
70+
},
71+
"python.autoComplete.extraPaths": [
72+
"src"
73+
]
74+
}
75+
```
76+
77+
6. Enjoy writing code, and being able to run `cg-trace` on your command line :tada:
78+
79+
### Using it
80+
81+
After following setup instructions above, you should be able to reproduce the example trace by running
82+
83+
```
84+
cg-trace --xml example/simple.xml example/simple.py
85+
```
86+
87+
You can also run traces for all tests and build a database by running `tests/create-test-db.sh`. Then run the queries inside the `ql/` directory.
88+
89+
## Tracing Limitations
90+
91+
### Multi-threading
92+
93+
Should be possible by using [`threading.setprofile`](https://docs.python.org/3.8/library/threading.html#threading.setprofile), but that hasn't been done yet.
94+
95+
### Code that uses `sys.setprofile`
96+
97+
Since that is our mechanism for recording calls, any code that uses `sys.setprofile` will not work together with the call-graph tracer.
98+
99+
### Class instantiation
100+
101+
Does not always fire off an event in the `sys.setprofile` function (neither in `sys.settrace`), so is not recorded. Example:
102+
103+
```
104+
r = range(10)
105+
```
106+
107+
when disassembled (`python -m dis <file>`):
108+
109+
```
110+
9 48 LOAD_NAME 7 (range)
111+
50 LOAD_CONST 5 (10)
112+
52 CALL_FUNCTION 1
113+
54 STORE_NAME 8 (r)
114+
```
115+
116+
but no event :disappointed:

python/tools/recorded-call-graph-metrics/cg_trace.py

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

0 commit comments

Comments
 (0)