instrumentation.c 70 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178
  1. #include "Python.h"
  2. #include "pycore_call.h"
  3. #include "pycore_frame.h"
  4. #include "pycore_interp.h"
  5. #include "pycore_long.h"
  6. #include "pycore_namespace.h"
  7. #include "pycore_object.h"
  8. #include "pycore_opcode.h"
  9. #include "pycore_pyerrors.h"
  10. #include "pycore_pystate.h"
  11. /* Uncomment this to dump debugging output when assertions fail */
  12. // #define INSTRUMENT_DEBUG 1
  13. PyObject _PyInstrumentation_DISABLE =
  14. {
  15. .ob_refcnt = _Py_IMMORTAL_REFCNT,
  16. .ob_type = &PyBaseObject_Type
  17. };
  18. PyObject _PyInstrumentation_MISSING =
  19. {
  20. .ob_refcnt = _Py_IMMORTAL_REFCNT,
  21. .ob_type = &PyBaseObject_Type
  22. };
  23. static const int8_t EVENT_FOR_OPCODE[256] = {
  24. [RETURN_CONST] = PY_MONITORING_EVENT_PY_RETURN,
  25. [INSTRUMENTED_RETURN_CONST] = PY_MONITORING_EVENT_PY_RETURN,
  26. [RETURN_VALUE] = PY_MONITORING_EVENT_PY_RETURN,
  27. [INSTRUMENTED_RETURN_VALUE] = PY_MONITORING_EVENT_PY_RETURN,
  28. [CALL] = PY_MONITORING_EVENT_CALL,
  29. [INSTRUMENTED_CALL] = PY_MONITORING_EVENT_CALL,
  30. [CALL_FUNCTION_EX] = PY_MONITORING_EVENT_CALL,
  31. [INSTRUMENTED_CALL_FUNCTION_EX] = PY_MONITORING_EVENT_CALL,
  32. [LOAD_SUPER_ATTR] = PY_MONITORING_EVENT_CALL,
  33. [INSTRUMENTED_LOAD_SUPER_ATTR] = PY_MONITORING_EVENT_CALL,
  34. [RESUME] = -1,
  35. [YIELD_VALUE] = PY_MONITORING_EVENT_PY_YIELD,
  36. [INSTRUMENTED_YIELD_VALUE] = PY_MONITORING_EVENT_PY_YIELD,
  37. [JUMP_FORWARD] = PY_MONITORING_EVENT_JUMP,
  38. [JUMP_BACKWARD] = PY_MONITORING_EVENT_JUMP,
  39. [POP_JUMP_IF_FALSE] = PY_MONITORING_EVENT_BRANCH,
  40. [POP_JUMP_IF_TRUE] = PY_MONITORING_EVENT_BRANCH,
  41. [POP_JUMP_IF_NONE] = PY_MONITORING_EVENT_BRANCH,
  42. [POP_JUMP_IF_NOT_NONE] = PY_MONITORING_EVENT_BRANCH,
  43. [INSTRUMENTED_JUMP_FORWARD] = PY_MONITORING_EVENT_JUMP,
  44. [INSTRUMENTED_JUMP_BACKWARD] = PY_MONITORING_EVENT_JUMP,
  45. [INSTRUMENTED_POP_JUMP_IF_FALSE] = PY_MONITORING_EVENT_BRANCH,
  46. [INSTRUMENTED_POP_JUMP_IF_TRUE] = PY_MONITORING_EVENT_BRANCH,
  47. [INSTRUMENTED_POP_JUMP_IF_NONE] = PY_MONITORING_EVENT_BRANCH,
  48. [INSTRUMENTED_POP_JUMP_IF_NOT_NONE] = PY_MONITORING_EVENT_BRANCH,
  49. [FOR_ITER] = PY_MONITORING_EVENT_BRANCH,
  50. [INSTRUMENTED_FOR_ITER] = PY_MONITORING_EVENT_BRANCH,
  51. [END_FOR] = PY_MONITORING_EVENT_STOP_ITERATION,
  52. [INSTRUMENTED_END_FOR] = PY_MONITORING_EVENT_STOP_ITERATION,
  53. [END_SEND] = PY_MONITORING_EVENT_STOP_ITERATION,
  54. [INSTRUMENTED_END_SEND] = PY_MONITORING_EVENT_STOP_ITERATION,
  55. };
  56. static const uint8_t DE_INSTRUMENT[256] = {
  57. [INSTRUMENTED_RESUME] = RESUME,
  58. [INSTRUMENTED_RETURN_VALUE] = RETURN_VALUE,
  59. [INSTRUMENTED_RETURN_CONST] = RETURN_CONST,
  60. [INSTRUMENTED_CALL] = CALL,
  61. [INSTRUMENTED_CALL_FUNCTION_EX] = CALL_FUNCTION_EX,
  62. [INSTRUMENTED_YIELD_VALUE] = YIELD_VALUE,
  63. [INSTRUMENTED_JUMP_FORWARD] = JUMP_FORWARD,
  64. [INSTRUMENTED_JUMP_BACKWARD] = JUMP_BACKWARD,
  65. [INSTRUMENTED_POP_JUMP_IF_FALSE] = POP_JUMP_IF_FALSE,
  66. [INSTRUMENTED_POP_JUMP_IF_TRUE] = POP_JUMP_IF_TRUE,
  67. [INSTRUMENTED_POP_JUMP_IF_NONE] = POP_JUMP_IF_NONE,
  68. [INSTRUMENTED_POP_JUMP_IF_NOT_NONE] = POP_JUMP_IF_NOT_NONE,
  69. [INSTRUMENTED_FOR_ITER] = FOR_ITER,
  70. [INSTRUMENTED_END_FOR] = END_FOR,
  71. [INSTRUMENTED_END_SEND] = END_SEND,
  72. [INSTRUMENTED_LOAD_SUPER_ATTR] = LOAD_SUPER_ATTR,
  73. };
  74. static const uint8_t INSTRUMENTED_OPCODES[256] = {
  75. [RETURN_CONST] = INSTRUMENTED_RETURN_CONST,
  76. [INSTRUMENTED_RETURN_CONST] = INSTRUMENTED_RETURN_CONST,
  77. [RETURN_VALUE] = INSTRUMENTED_RETURN_VALUE,
  78. [INSTRUMENTED_RETURN_VALUE] = INSTRUMENTED_RETURN_VALUE,
  79. [CALL] = INSTRUMENTED_CALL,
  80. [INSTRUMENTED_CALL] = INSTRUMENTED_CALL,
  81. [CALL_FUNCTION_EX] = INSTRUMENTED_CALL_FUNCTION_EX,
  82. [INSTRUMENTED_CALL_FUNCTION_EX] = INSTRUMENTED_CALL_FUNCTION_EX,
  83. [YIELD_VALUE] = INSTRUMENTED_YIELD_VALUE,
  84. [INSTRUMENTED_YIELD_VALUE] = INSTRUMENTED_YIELD_VALUE,
  85. [RESUME] = INSTRUMENTED_RESUME,
  86. [INSTRUMENTED_RESUME] = INSTRUMENTED_RESUME,
  87. [JUMP_FORWARD] = INSTRUMENTED_JUMP_FORWARD,
  88. [INSTRUMENTED_JUMP_FORWARD] = INSTRUMENTED_JUMP_FORWARD,
  89. [JUMP_BACKWARD] = INSTRUMENTED_JUMP_BACKWARD,
  90. [INSTRUMENTED_JUMP_BACKWARD] = INSTRUMENTED_JUMP_BACKWARD,
  91. [POP_JUMP_IF_FALSE] = INSTRUMENTED_POP_JUMP_IF_FALSE,
  92. [INSTRUMENTED_POP_JUMP_IF_FALSE] = INSTRUMENTED_POP_JUMP_IF_FALSE,
  93. [POP_JUMP_IF_TRUE] = INSTRUMENTED_POP_JUMP_IF_TRUE,
  94. [INSTRUMENTED_POP_JUMP_IF_TRUE] = INSTRUMENTED_POP_JUMP_IF_TRUE,
  95. [POP_JUMP_IF_NONE] = INSTRUMENTED_POP_JUMP_IF_NONE,
  96. [INSTRUMENTED_POP_JUMP_IF_NONE] = INSTRUMENTED_POP_JUMP_IF_NONE,
  97. [POP_JUMP_IF_NOT_NONE] = INSTRUMENTED_POP_JUMP_IF_NOT_NONE,
  98. [INSTRUMENTED_POP_JUMP_IF_NOT_NONE] = INSTRUMENTED_POP_JUMP_IF_NOT_NONE,
  99. [END_FOR] = INSTRUMENTED_END_FOR,
  100. [INSTRUMENTED_END_FOR] = INSTRUMENTED_END_FOR,
  101. [END_SEND] = INSTRUMENTED_END_SEND,
  102. [INSTRUMENTED_END_SEND] = INSTRUMENTED_END_SEND,
  103. [FOR_ITER] = INSTRUMENTED_FOR_ITER,
  104. [INSTRUMENTED_FOR_ITER] = INSTRUMENTED_FOR_ITER,
  105. [LOAD_SUPER_ATTR] = INSTRUMENTED_LOAD_SUPER_ATTR,
  106. [INSTRUMENTED_LOAD_SUPER_ATTR] = INSTRUMENTED_LOAD_SUPER_ATTR,
  107. [INSTRUMENTED_LINE] = INSTRUMENTED_LINE,
  108. [INSTRUMENTED_INSTRUCTION] = INSTRUMENTED_INSTRUCTION,
  109. };
  110. static inline bool
  111. opcode_has_event(int opcode)
  112. {
  113. return (
  114. opcode < INSTRUMENTED_LINE &&
  115. INSTRUMENTED_OPCODES[opcode] > 0
  116. );
  117. }
  118. static inline bool
  119. is_instrumented(int opcode)
  120. {
  121. assert(opcode != 0);
  122. assert(opcode != RESERVED);
  123. return opcode >= MIN_INSTRUMENTED_OPCODE;
  124. }
  125. #ifndef NDEBUG
  126. static inline bool
  127. monitors_equals(_Py_LocalMonitors a, _Py_LocalMonitors b)
  128. {
  129. for (int i = 0; i < _PY_MONITORING_LOCAL_EVENTS; i++) {
  130. if (a.tools[i] != b.tools[i]) {
  131. return false;
  132. }
  133. }
  134. return true;
  135. }
  136. #endif
  137. static inline _Py_LocalMonitors
  138. monitors_sub(_Py_LocalMonitors a, _Py_LocalMonitors b)
  139. {
  140. _Py_LocalMonitors res;
  141. for (int i = 0; i < _PY_MONITORING_LOCAL_EVENTS; i++) {
  142. res.tools[i] = a.tools[i] & ~b.tools[i];
  143. }
  144. return res;
  145. }
  146. #ifndef NDEBUG
  147. static inline _Py_LocalMonitors
  148. monitors_and(_Py_LocalMonitors a, _Py_LocalMonitors b)
  149. {
  150. _Py_LocalMonitors res;
  151. for (int i = 0; i < _PY_MONITORING_LOCAL_EVENTS; i++) {
  152. res.tools[i] = a.tools[i] & b.tools[i];
  153. }
  154. return res;
  155. }
  156. #endif
  157. /* The union of the *local* events in a and b.
  158. * Global events like RAISE are ignored.
  159. * Used for instrumentation, as only local
  160. * events get instrumented.
  161. */
  162. static inline _Py_LocalMonitors
  163. local_union(_Py_GlobalMonitors a, _Py_LocalMonitors b)
  164. {
  165. _Py_LocalMonitors res;
  166. for (int i = 0; i < _PY_MONITORING_LOCAL_EVENTS; i++) {
  167. res.tools[i] = a.tools[i] | b.tools[i];
  168. }
  169. return res;
  170. }
  171. static inline bool
  172. monitors_are_empty(_Py_LocalMonitors m)
  173. {
  174. for (int i = 0; i < _PY_MONITORING_LOCAL_EVENTS; i++) {
  175. if (m.tools[i]) {
  176. return false;
  177. }
  178. }
  179. return true;
  180. }
  181. static inline bool
  182. multiple_tools(_Py_LocalMonitors *m)
  183. {
  184. for (int i = 0; i < _PY_MONITORING_LOCAL_EVENTS; i++) {
  185. if (_Py_popcount32(m->tools[i]) > 1) {
  186. return true;
  187. }
  188. }
  189. return false;
  190. }
  191. static inline _PyMonitoringEventSet
  192. get_local_events(_Py_LocalMonitors *m, int tool_id)
  193. {
  194. _PyMonitoringEventSet result = 0;
  195. for (int e = 0; e < _PY_MONITORING_LOCAL_EVENTS; e++) {
  196. if ((m->tools[e] >> tool_id) & 1) {
  197. result |= (1 << e);
  198. }
  199. }
  200. return result;
  201. }
  202. static inline _PyMonitoringEventSet
  203. get_events(_Py_GlobalMonitors *m, int tool_id)
  204. {
  205. _PyMonitoringEventSet result = 0;
  206. for (int e = 0; e < _PY_MONITORING_UNGROUPED_EVENTS; e++) {
  207. if ((m->tools[e] >> tool_id) & 1) {
  208. result |= (1 << e);
  209. }
  210. }
  211. return result;
  212. }
  213. /* Line delta.
  214. * 8 bit value.
  215. * if line_delta == -128:
  216. * line = None # represented as -1
  217. * elif line_delta == -127:
  218. * line = PyCode_Addr2Line(code, offset * sizeof(_Py_CODEUNIT));
  219. * else:
  220. * line = first_line + (offset >> OFFSET_SHIFT) + line_delta;
  221. */
  222. #define NO_LINE -128
  223. #define COMPUTED_LINE -127
  224. #define OFFSET_SHIFT 4
  225. static int8_t
  226. compute_line_delta(PyCodeObject *code, int offset, int line)
  227. {
  228. if (line < 0) {
  229. return NO_LINE;
  230. }
  231. int delta = line - code->co_firstlineno - (offset >> OFFSET_SHIFT);
  232. if (delta <= INT8_MAX && delta > COMPUTED_LINE) {
  233. return delta;
  234. }
  235. return COMPUTED_LINE;
  236. }
  237. static int
  238. compute_line(PyCodeObject *code, int offset, int8_t line_delta)
  239. {
  240. if (line_delta > COMPUTED_LINE) {
  241. return code->co_firstlineno + (offset >> OFFSET_SHIFT) + line_delta;
  242. }
  243. if (line_delta == NO_LINE) {
  244. return -1;
  245. }
  246. assert(line_delta == COMPUTED_LINE);
  247. /* Look it up */
  248. return PyCode_Addr2Line(code, offset * sizeof(_Py_CODEUNIT));
  249. }
  250. static int
  251. instruction_length(PyCodeObject *code, int offset)
  252. {
  253. int opcode = _PyCode_CODE(code)[offset].op.code;
  254. assert(opcode != 0);
  255. assert(opcode != RESERVED);
  256. if (opcode == INSTRUMENTED_LINE) {
  257. opcode = code->_co_monitoring->lines[offset].original_opcode;
  258. }
  259. if (opcode == INSTRUMENTED_INSTRUCTION) {
  260. opcode = code->_co_monitoring->per_instruction_opcodes[offset];
  261. }
  262. int deinstrumented = DE_INSTRUMENT[opcode];
  263. if (deinstrumented) {
  264. opcode = deinstrumented;
  265. }
  266. else {
  267. opcode = _PyOpcode_Deopt[opcode];
  268. }
  269. assert(opcode != 0);
  270. assert(!is_instrumented(opcode));
  271. assert(opcode == _PyOpcode_Deopt[opcode]);
  272. return 1 + _PyOpcode_Caches[opcode];
  273. }
  274. #ifdef INSTRUMENT_DEBUG
  275. static void
  276. dump_instrumentation_data_tools(PyCodeObject *code, uint8_t *tools, int i, FILE*out)
  277. {
  278. if (tools == NULL) {
  279. fprintf(out, "tools = NULL");
  280. }
  281. else {
  282. fprintf(out, "tools = %d", tools[i]);
  283. }
  284. }
  285. static void
  286. dump_instrumentation_data_lines(PyCodeObject *code, _PyCoLineInstrumentationData *lines, int i, FILE*out)
  287. {
  288. if (lines == NULL) {
  289. fprintf(out, ", lines = NULL");
  290. }
  291. else if (lines[i].original_opcode == 0) {
  292. fprintf(out, ", lines = {original_opcode = No LINE (0), line_delta = %d)", lines[i].line_delta);
  293. }
  294. else {
  295. fprintf(out, ", lines = {original_opcode = %s, line_delta = %d)", _PyOpcode_OpName[lines[i].original_opcode], lines[i].line_delta);
  296. }
  297. }
  298. static void
  299. dump_instrumentation_data_line_tools(PyCodeObject *code, uint8_t *line_tools, int i, FILE*out)
  300. {
  301. if (line_tools == NULL) {
  302. fprintf(out, ", line_tools = NULL");
  303. }
  304. else {
  305. fprintf(out, ", line_tools = %d", line_tools[i]);
  306. }
  307. }
  308. static void
  309. dump_instrumentation_data_per_instruction(PyCodeObject *code, _PyCoMonitoringData *data, int i, FILE*out)
  310. {
  311. if (data->per_instruction_opcodes == NULL) {
  312. fprintf(out, ", per-inst opcode = NULL");
  313. }
  314. else {
  315. fprintf(out, ", per-inst opcode = %s", _PyOpcode_OpName[data->per_instruction_opcodes[i]]);
  316. }
  317. if (data->per_instruction_tools == NULL) {
  318. fprintf(out, ", per-inst tools = NULL");
  319. }
  320. else {
  321. fprintf(out, ", per-inst tools = %d", data->per_instruction_tools[i]);
  322. }
  323. }
  324. static void
  325. dump_global_monitors(const char *prefix, _Py_GlobalMonitors monitors, FILE*out)
  326. {
  327. fprintf(out, "%s monitors:\n", prefix);
  328. for (int event = 0; event < _PY_MONITORING_UNGROUPED_EVENTS; event++) {
  329. fprintf(out, " Event %d: Tools %x\n", event, monitors.tools[event]);
  330. }
  331. }
  332. static void
  333. dump_local_monitors(const char *prefix, _Py_LocalMonitors monitors, FILE*out)
  334. {
  335. fprintf(out, "%s monitors:\n", prefix);
  336. for (int event = 0; event < _PY_MONITORING_LOCAL_EVENTS; event++) {
  337. fprintf(out, " Event %d: Tools %x\n", event, monitors.tools[event]);
  338. }
  339. }
  340. /* No error checking -- Don't use this for anything but experimental debugging */
  341. static void
  342. dump_instrumentation_data(PyCodeObject *code, int star, FILE*out)
  343. {
  344. _PyCoMonitoringData *data = code->_co_monitoring;
  345. fprintf(out, "\n");
  346. PyObject_Print(code->co_name, out, Py_PRINT_RAW);
  347. fprintf(out, "\n");
  348. if (data == NULL) {
  349. fprintf(out, "NULL\n");
  350. return;
  351. }
  352. dump_global_monitors("Global", _PyInterpreterState_GET()->monitors, out);
  353. dump_local_monitors("Code", data->local_monitors, out);
  354. dump_local_monitors("Active", data->active_monitors, out);
  355. int code_len = (int)Py_SIZE(code);
  356. bool starred = false;
  357. for (int i = 0; i < code_len; i += instruction_length(code, i)) {
  358. _Py_CODEUNIT *instr = &_PyCode_CODE(code)[i];
  359. int opcode = instr->op.code;
  360. if (i == star) {
  361. fprintf(out, "** ");
  362. starred = true;
  363. }
  364. fprintf(out, "Offset: %d, line: %d %s: ", i, PyCode_Addr2Line(code, i*2), _PyOpcode_OpName[opcode]);
  365. dump_instrumentation_data_tools(code, data->tools, i, out);
  366. dump_instrumentation_data_lines(code, data->lines, i, out);
  367. dump_instrumentation_data_line_tools(code, data->line_tools, i, out);
  368. dump_instrumentation_data_per_instruction(code, data, i, out);
  369. fprintf(out, "\n");
  370. ;
  371. }
  372. if (!starred && star >= 0) {
  373. fprintf(out, "Error offset not at valid instruction offset: %d\n", star);
  374. fprintf(out, " ");
  375. dump_instrumentation_data_tools(code, data->tools, star, out);
  376. dump_instrumentation_data_lines(code, data->lines, star, out);
  377. dump_instrumentation_data_line_tools(code, data->line_tools, star, out);
  378. dump_instrumentation_data_per_instruction(code, data, star, out);
  379. fprintf(out, "\n");
  380. }
  381. }
  382. #define CHECK(test) do { \
  383. if (!(test)) { \
  384. dump_instrumentation_data(code, i, stderr); \
  385. } \
  386. assert(test); \
  387. } while (0)
  388. static bool
  389. valid_opcode(int opcode)
  390. {
  391. if (opcode > 0 &&
  392. opcode != RESERVED &&
  393. opcode < 255 &&
  394. _PyOpcode_OpName[opcode] &&
  395. _PyOpcode_OpName[opcode][0] != '<')
  396. {
  397. return true;
  398. }
  399. return false;
  400. }
  401. static void
  402. sanity_check_instrumentation(PyCodeObject *code)
  403. {
  404. _PyCoMonitoringData *data = code->_co_monitoring;
  405. if (data == NULL) {
  406. return;
  407. }
  408. _Py_GlobalMonitors global_monitors = _PyInterpreterState_GET()->monitors;
  409. _Py_LocalMonitors active_monitors;
  410. if (code->_co_monitoring) {
  411. _Py_LocalMonitors local_monitors = code->_co_monitoring->local_monitors;
  412. active_monitors = local_union(global_monitors, local_monitors);
  413. }
  414. else {
  415. _Py_LocalMonitors empty = (_Py_LocalMonitors) { 0 };
  416. active_monitors = local_union(global_monitors, empty);
  417. }
  418. assert(monitors_equals(
  419. code->_co_monitoring->active_monitors,
  420. active_monitors));
  421. int code_len = (int)Py_SIZE(code);
  422. for (int i = 0; i < code_len;) {
  423. _Py_CODEUNIT *instr = &_PyCode_CODE(code)[i];
  424. int opcode = instr->op.code;
  425. int base_opcode = _Py_GetBaseOpcode(code, i);
  426. CHECK(valid_opcode(opcode));
  427. CHECK(valid_opcode(base_opcode));
  428. if (opcode == INSTRUMENTED_INSTRUCTION) {
  429. opcode = data->per_instruction_opcodes[i];
  430. if (!is_instrumented(opcode)) {
  431. CHECK(_PyOpcode_Deopt[opcode] == opcode);
  432. }
  433. if (data->per_instruction_tools) {
  434. uint8_t tools = active_monitors.tools[PY_MONITORING_EVENT_INSTRUCTION];
  435. CHECK((tools & data->per_instruction_tools[i]) == data->per_instruction_tools[i]);
  436. }
  437. }
  438. if (opcode == INSTRUMENTED_LINE) {
  439. CHECK(data->lines);
  440. CHECK(valid_opcode(data->lines[i].original_opcode));
  441. opcode = data->lines[i].original_opcode;
  442. CHECK(opcode != END_FOR);
  443. CHECK(opcode != RESUME);
  444. CHECK(opcode != RESUME_CHECK);
  445. CHECK(opcode != INSTRUMENTED_RESUME);
  446. if (!is_instrumented(opcode)) {
  447. CHECK(_PyOpcode_Deopt[opcode] == opcode);
  448. }
  449. CHECK(opcode != INSTRUMENTED_LINE);
  450. }
  451. else if (data->lines) {
  452. /* If original_opcode is INSTRUMENTED_INSTRUCTION
  453. * *and* we are executing a INSTRUMENTED_LINE instruction
  454. * that has de-instrumented itself, then we will execute
  455. * an invalid INSTRUMENTED_INSTRUCTION */
  456. CHECK(data->lines[i].original_opcode != INSTRUMENTED_INSTRUCTION);
  457. }
  458. if (opcode == INSTRUMENTED_INSTRUCTION) {
  459. CHECK(data->per_instruction_opcodes[i] != 0);
  460. opcode = data->per_instruction_opcodes[i];
  461. }
  462. if (is_instrumented(opcode)) {
  463. CHECK(DE_INSTRUMENT[opcode] == base_opcode);
  464. int event = EVENT_FOR_OPCODE[DE_INSTRUMENT[opcode]];
  465. if (event < 0) {
  466. /* RESUME fixup */
  467. event = instr->op.arg ? 1: 0;
  468. }
  469. CHECK(active_monitors.tools[event] != 0);
  470. }
  471. if (data->lines && base_opcode != END_FOR) {
  472. int line1 = compute_line(code, i, data->lines[i].line_delta);
  473. int line2 = PyCode_Addr2Line(code, i*sizeof(_Py_CODEUNIT));
  474. CHECK(line1 == line2);
  475. }
  476. CHECK(valid_opcode(opcode));
  477. if (data->tools) {
  478. uint8_t local_tools = data->tools[i];
  479. if (opcode_has_event(base_opcode)) {
  480. int event = EVENT_FOR_OPCODE[base_opcode];
  481. if (event == -1) {
  482. /* RESUME fixup */
  483. event = _PyCode_CODE(code)[i].op.arg;
  484. }
  485. CHECK((active_monitors.tools[event] & local_tools) == local_tools);
  486. }
  487. else {
  488. CHECK(local_tools == 0xff);
  489. }
  490. }
  491. i += instruction_length(code, i);
  492. assert(i <= code_len);
  493. }
  494. }
  495. #else
  496. #define CHECK(test) assert(test)
  497. #endif
  498. /* Get the underlying opcode, stripping instrumentation */
  499. int _Py_GetBaseOpcode(PyCodeObject *code, int i)
  500. {
  501. int opcode = _PyCode_CODE(code)[i].op.code;
  502. if (opcode == INSTRUMENTED_LINE) {
  503. opcode = code->_co_monitoring->lines[i].original_opcode;
  504. }
  505. if (opcode == INSTRUMENTED_INSTRUCTION) {
  506. opcode = code->_co_monitoring->per_instruction_opcodes[i];
  507. }
  508. CHECK(opcode != INSTRUMENTED_INSTRUCTION);
  509. CHECK(opcode != INSTRUMENTED_LINE);
  510. int deinstrumented = DE_INSTRUMENT[opcode];
  511. if (deinstrumented) {
  512. return deinstrumented;
  513. }
  514. return _PyOpcode_Deopt[opcode];
  515. }
  516. static void
  517. de_instrument(PyCodeObject *code, int i, int event)
  518. {
  519. assert(event != PY_MONITORING_EVENT_INSTRUCTION);
  520. assert(event != PY_MONITORING_EVENT_LINE);
  521. _Py_CODEUNIT *instr = &_PyCode_CODE(code)[i];
  522. uint8_t *opcode_ptr = &instr->op.code;
  523. int opcode = *opcode_ptr;
  524. if (opcode == INSTRUMENTED_LINE) {
  525. opcode_ptr = &code->_co_monitoring->lines[i].original_opcode;
  526. opcode = *opcode_ptr;
  527. }
  528. if (opcode == INSTRUMENTED_INSTRUCTION) {
  529. opcode_ptr = &code->_co_monitoring->per_instruction_opcodes[i];
  530. opcode = *opcode_ptr;
  531. }
  532. int deinstrumented = DE_INSTRUMENT[opcode];
  533. if (deinstrumented == 0) {
  534. return;
  535. }
  536. CHECK(_PyOpcode_Deopt[deinstrumented] == deinstrumented);
  537. *opcode_ptr = deinstrumented;
  538. if (_PyOpcode_Caches[deinstrumented]) {
  539. instr[1].cache = adaptive_counter_warmup();
  540. }
  541. }
  542. static void
  543. de_instrument_line(PyCodeObject *code, int i)
  544. {
  545. _Py_CODEUNIT *instr = &_PyCode_CODE(code)[i];
  546. int opcode = instr->op.code;
  547. if (opcode != INSTRUMENTED_LINE) {
  548. return;
  549. }
  550. _PyCoLineInstrumentationData *lines = &code->_co_monitoring->lines[i];
  551. int original_opcode = lines->original_opcode;
  552. if (original_opcode == INSTRUMENTED_INSTRUCTION) {
  553. lines->original_opcode = code->_co_monitoring->per_instruction_opcodes[i];
  554. }
  555. CHECK(original_opcode != 0);
  556. CHECK(original_opcode == _PyOpcode_Deopt[original_opcode]);
  557. instr->op.code = original_opcode;
  558. if (_PyOpcode_Caches[original_opcode]) {
  559. instr[1].cache = adaptive_counter_warmup();
  560. }
  561. assert(instr->op.code != INSTRUMENTED_LINE);
  562. }
  563. static void
  564. de_instrument_per_instruction(PyCodeObject *code, int i)
  565. {
  566. _Py_CODEUNIT *instr = &_PyCode_CODE(code)[i];
  567. uint8_t *opcode_ptr = &instr->op.code;
  568. int opcode = *opcode_ptr;
  569. if (opcode == INSTRUMENTED_LINE) {
  570. opcode_ptr = &code->_co_monitoring->lines[i].original_opcode;
  571. opcode = *opcode_ptr;
  572. }
  573. if (opcode != INSTRUMENTED_INSTRUCTION) {
  574. return;
  575. }
  576. int original_opcode = code->_co_monitoring->per_instruction_opcodes[i];
  577. CHECK(original_opcode != 0);
  578. CHECK(original_opcode == _PyOpcode_Deopt[original_opcode]);
  579. *opcode_ptr = original_opcode;
  580. if (_PyOpcode_Caches[original_opcode]) {
  581. instr[1].cache = adaptive_counter_warmup();
  582. }
  583. assert(*opcode_ptr != INSTRUMENTED_INSTRUCTION);
  584. assert(instr->op.code != INSTRUMENTED_INSTRUCTION);
  585. /* Keep things clean for sanity check */
  586. code->_co_monitoring->per_instruction_opcodes[i] = 0;
  587. }
  588. static void
  589. instrument(PyCodeObject *code, int i)
  590. {
  591. _Py_CODEUNIT *instr = &_PyCode_CODE(code)[i];
  592. uint8_t *opcode_ptr = &instr->op.code;
  593. int opcode =*opcode_ptr;
  594. if (opcode == INSTRUMENTED_LINE) {
  595. _PyCoLineInstrumentationData *lines = &code->_co_monitoring->lines[i];
  596. opcode_ptr = &lines->original_opcode;
  597. opcode = *opcode_ptr;
  598. }
  599. if (opcode == INSTRUMENTED_INSTRUCTION) {
  600. opcode_ptr = &code->_co_monitoring->per_instruction_opcodes[i];
  601. opcode = *opcode_ptr;
  602. CHECK(opcode != INSTRUMENTED_INSTRUCTION && opcode != INSTRUMENTED_LINE);
  603. CHECK(opcode == _PyOpcode_Deopt[opcode]);
  604. }
  605. CHECK(opcode != 0);
  606. if (!is_instrumented(opcode)) {
  607. int deopt = _PyOpcode_Deopt[opcode];
  608. int instrumented = INSTRUMENTED_OPCODES[deopt];
  609. assert(instrumented);
  610. *opcode_ptr = instrumented;
  611. if (_PyOpcode_Caches[deopt]) {
  612. instr[1].cache = adaptive_counter_warmup();
  613. }
  614. }
  615. }
  616. static void
  617. instrument_line(PyCodeObject *code, int i)
  618. {
  619. uint8_t *opcode_ptr = &_PyCode_CODE(code)[i].op.code;
  620. int opcode = *opcode_ptr;
  621. if (opcode == INSTRUMENTED_LINE) {
  622. return;
  623. }
  624. _PyCoLineInstrumentationData *lines = &code->_co_monitoring->lines[i];
  625. lines->original_opcode = _PyOpcode_Deopt[opcode];
  626. CHECK(lines->original_opcode > 0);
  627. *opcode_ptr = INSTRUMENTED_LINE;
  628. }
  629. static void
  630. instrument_per_instruction(PyCodeObject *code, int i)
  631. {
  632. _Py_CODEUNIT *instr = &_PyCode_CODE(code)[i];
  633. uint8_t *opcode_ptr = &instr->op.code;
  634. int opcode = *opcode_ptr;
  635. if (opcode == INSTRUMENTED_LINE) {
  636. _PyCoLineInstrumentationData *lines = &code->_co_monitoring->lines[i];
  637. opcode_ptr = &lines->original_opcode;
  638. opcode = *opcode_ptr;
  639. }
  640. if (opcode == INSTRUMENTED_INSTRUCTION) {
  641. assert(code->_co_monitoring->per_instruction_opcodes[i] > 0);
  642. return;
  643. }
  644. CHECK(opcode != 0);
  645. if (is_instrumented(opcode)) {
  646. code->_co_monitoring->per_instruction_opcodes[i] = opcode;
  647. }
  648. else {
  649. assert(opcode != 0);
  650. assert(_PyOpcode_Deopt[opcode] != 0);
  651. assert(_PyOpcode_Deopt[opcode] != RESUME);
  652. code->_co_monitoring->per_instruction_opcodes[i] = _PyOpcode_Deopt[opcode];
  653. }
  654. assert(code->_co_monitoring->per_instruction_opcodes[i] > 0);
  655. *opcode_ptr = INSTRUMENTED_INSTRUCTION;
  656. }
  657. static void
  658. remove_tools(PyCodeObject * code, int offset, int event, int tools)
  659. {
  660. assert(event != PY_MONITORING_EVENT_LINE);
  661. assert(event != PY_MONITORING_EVENT_INSTRUCTION);
  662. assert(PY_MONITORING_IS_INSTRUMENTED_EVENT(event));
  663. assert(opcode_has_event(_Py_GetBaseOpcode(code, offset)));
  664. _PyCoMonitoringData *monitoring = code->_co_monitoring;
  665. if (monitoring && monitoring->tools) {
  666. monitoring->tools[offset] &= ~tools;
  667. if (monitoring->tools[offset] == 0) {
  668. de_instrument(code, offset, event);
  669. }
  670. }
  671. else {
  672. /* Single tool */
  673. uint8_t single_tool = code->_co_monitoring->active_monitors.tools[event];
  674. assert(_Py_popcount32(single_tool) <= 1);
  675. if (((single_tool & tools) == single_tool)) {
  676. de_instrument(code, offset, event);
  677. }
  678. }
  679. }
  680. #ifndef NDEBUG
  681. static bool
  682. tools_is_subset_for_event(PyCodeObject * code, int event, int tools)
  683. {
  684. int global_tools = PyInterpreterState_Get()->monitors.tools[event];
  685. int local_tools = code->_co_monitoring->local_monitors.tools[event];
  686. return tools == ((global_tools | local_tools) & tools);
  687. }
  688. #endif
  689. static void
  690. remove_line_tools(PyCodeObject * code, int offset, int tools)
  691. {
  692. assert(code->_co_monitoring);
  693. if (code->_co_monitoring->line_tools)
  694. {
  695. uint8_t *toolsptr = &code->_co_monitoring->line_tools[offset];
  696. *toolsptr &= ~tools;
  697. if (*toolsptr == 0 ) {
  698. de_instrument_line(code, offset);
  699. }
  700. }
  701. else {
  702. /* Single tool */
  703. uint8_t single_tool = code->_co_monitoring->active_monitors.tools[PY_MONITORING_EVENT_LINE];
  704. assert(_Py_popcount32(single_tool) <= 1);
  705. if (((single_tool & tools) == single_tool)) {
  706. de_instrument_line(code, offset);
  707. }
  708. }
  709. }
  710. static void
  711. add_tools(PyCodeObject * code, int offset, int event, int tools)
  712. {
  713. assert(event != PY_MONITORING_EVENT_LINE);
  714. assert(event != PY_MONITORING_EVENT_INSTRUCTION);
  715. assert(PY_MONITORING_IS_INSTRUMENTED_EVENT(event));
  716. assert(code->_co_monitoring);
  717. if (code->_co_monitoring &&
  718. code->_co_monitoring->tools
  719. ) {
  720. code->_co_monitoring->tools[offset] |= tools;
  721. }
  722. else {
  723. /* Single tool */
  724. assert(_Py_popcount32(tools) == 1);
  725. assert(tools_is_subset_for_event(code, event, tools));
  726. }
  727. instrument(code, offset);
  728. }
  729. static void
  730. add_line_tools(PyCodeObject * code, int offset, int tools)
  731. {
  732. assert(tools_is_subset_for_event(code, PY_MONITORING_EVENT_LINE, tools));
  733. assert(code->_co_monitoring);
  734. if (code->_co_monitoring->line_tools) {
  735. code->_co_monitoring->line_tools[offset] |= tools;
  736. }
  737. else {
  738. /* Single tool */
  739. assert(_Py_popcount32(tools) == 1);
  740. }
  741. instrument_line(code, offset);
  742. }
  743. static void
  744. add_per_instruction_tools(PyCodeObject * code, int offset, int tools)
  745. {
  746. assert(tools_is_subset_for_event(code, PY_MONITORING_EVENT_INSTRUCTION, tools));
  747. assert(code->_co_monitoring);
  748. if (code->_co_monitoring->per_instruction_tools) {
  749. code->_co_monitoring->per_instruction_tools[offset] |= tools;
  750. }
  751. else {
  752. /* Single tool */
  753. assert(_Py_popcount32(tools) == 1);
  754. }
  755. instrument_per_instruction(code, offset);
  756. }
  757. static void
  758. remove_per_instruction_tools(PyCodeObject * code, int offset, int tools)
  759. {
  760. assert(code->_co_monitoring);
  761. if (code->_co_monitoring->per_instruction_tools) {
  762. uint8_t *toolsptr = &code->_co_monitoring->per_instruction_tools[offset];
  763. *toolsptr &= ~tools;
  764. if (*toolsptr == 0) {
  765. de_instrument_per_instruction(code, offset);
  766. }
  767. }
  768. else {
  769. /* Single tool */
  770. uint8_t single_tool = code->_co_monitoring->active_monitors.tools[PY_MONITORING_EVENT_INSTRUCTION];
  771. assert(_Py_popcount32(single_tool) <= 1);
  772. if (((single_tool & tools) == single_tool)) {
  773. de_instrument_per_instruction(code, offset);
  774. }
  775. }
  776. }
  777. /* Return 1 if DISABLE returned, -1 if error, 0 otherwise */
  778. static int
  779. call_one_instrument(
  780. PyInterpreterState *interp, PyThreadState *tstate, PyObject **args,
  781. Py_ssize_t nargsf, int8_t tool, int event)
  782. {
  783. assert(0 <= tool && tool < 8);
  784. assert(tstate->tracing == 0);
  785. PyObject *instrument = interp->monitoring_callables[tool][event];
  786. if (instrument == NULL) {
  787. return 0;
  788. }
  789. int old_what = tstate->what_event;
  790. tstate->what_event = event;
  791. tstate->tracing++;
  792. PyObject *res = _PyObject_VectorcallTstate(tstate, instrument, args, nargsf, NULL);
  793. tstate->tracing--;
  794. tstate->what_event = old_what;
  795. if (res == NULL) {
  796. return -1;
  797. }
  798. Py_DECREF(res);
  799. return (res == &_PyInstrumentation_DISABLE);
  800. }
  801. static const int8_t MOST_SIGNIFICANT_BITS[16] = {
  802. -1, 0, 1, 1,
  803. 2, 2, 2, 2,
  804. 3, 3, 3, 3,
  805. 3, 3, 3, 3,
  806. };
  807. /* We could use _Py_bit_length here, but that is designed for larger (32/64)
  808. * bit ints, and can perform relatively poorly on platforms without the
  809. * necessary intrinsics. */
  810. static inline int most_significant_bit(uint8_t bits) {
  811. assert(bits != 0);
  812. if (bits > 15) {
  813. return MOST_SIGNIFICANT_BITS[bits>>4]+4;
  814. }
  815. return MOST_SIGNIFICANT_BITS[bits];
  816. }
  817. static bool
  818. is_version_up_to_date(PyCodeObject *code, PyInterpreterState *interp)
  819. {
  820. return interp->monitoring_version == code->_co_instrumentation_version;
  821. }
  822. #ifndef NDEBUG
  823. static bool
  824. instrumentation_cross_checks(PyInterpreterState *interp, PyCodeObject *code)
  825. {
  826. _Py_LocalMonitors expected = local_union(
  827. interp->monitors,
  828. code->_co_monitoring->local_monitors);
  829. return monitors_equals(code->_co_monitoring->active_monitors, expected);
  830. }
  831. #endif
  832. static inline uint8_t
  833. get_tools_for_instruction(PyCodeObject *code, PyInterpreterState *interp, int i, int event)
  834. {
  835. uint8_t tools;
  836. assert(event != PY_MONITORING_EVENT_LINE);
  837. assert(event != PY_MONITORING_EVENT_INSTRUCTION);
  838. if (event >= _PY_MONITORING_UNGROUPED_EVENTS) {
  839. assert(event == PY_MONITORING_EVENT_C_RAISE ||
  840. event == PY_MONITORING_EVENT_C_RETURN);
  841. event = PY_MONITORING_EVENT_CALL;
  842. }
  843. if (PY_MONITORING_IS_INSTRUMENTED_EVENT(event)) {
  844. CHECK(is_version_up_to_date(code, interp));
  845. CHECK(instrumentation_cross_checks(interp, code));
  846. if (code->_co_monitoring->tools) {
  847. tools = code->_co_monitoring->tools[i];
  848. }
  849. else {
  850. tools = code->_co_monitoring->active_monitors.tools[event];
  851. }
  852. }
  853. else {
  854. tools = interp->monitors.tools[event];
  855. }
  856. return tools;
  857. }
  858. static const char *const event_names [] = {
  859. [PY_MONITORING_EVENT_PY_START] = "PY_START",
  860. [PY_MONITORING_EVENT_PY_RESUME] = "PY_RESUME",
  861. [PY_MONITORING_EVENT_PY_RETURN] = "PY_RETURN",
  862. [PY_MONITORING_EVENT_PY_YIELD] = "PY_YIELD",
  863. [PY_MONITORING_EVENT_CALL] = "CALL",
  864. [PY_MONITORING_EVENT_LINE] = "LINE",
  865. [PY_MONITORING_EVENT_INSTRUCTION] = "INSTRUCTION",
  866. [PY_MONITORING_EVENT_JUMP] = "JUMP",
  867. [PY_MONITORING_EVENT_BRANCH] = "BRANCH",
  868. [PY_MONITORING_EVENT_C_RETURN] = "C_RETURN",
  869. [PY_MONITORING_EVENT_PY_THROW] = "PY_THROW",
  870. [PY_MONITORING_EVENT_RAISE] = "RAISE",
  871. [PY_MONITORING_EVENT_RERAISE] = "RERAISE",
  872. [PY_MONITORING_EVENT_EXCEPTION_HANDLED] = "EXCEPTION_HANDLED",
  873. [PY_MONITORING_EVENT_C_RAISE] = "C_RAISE",
  874. [PY_MONITORING_EVENT_PY_UNWIND] = "PY_UNWIND",
  875. [PY_MONITORING_EVENT_STOP_ITERATION] = "STOP_ITERATION",
  876. };
  877. static int
  878. call_instrumentation_vector(
  879. PyThreadState *tstate, int event,
  880. _PyInterpreterFrame *frame, _Py_CODEUNIT *instr, Py_ssize_t nargs, PyObject *args[])
  881. {
  882. if (tstate->tracing) {
  883. return 0;
  884. }
  885. assert(!_PyErr_Occurred(tstate));
  886. assert(args[0] == NULL);
  887. PyCodeObject *code = frame->f_code;
  888. assert(code->_co_instrumentation_version == tstate->interp->monitoring_version);
  889. assert(is_version_up_to_date(code, tstate->interp));
  890. assert(instrumentation_cross_checks(tstate->interp, code));
  891. assert(args[1] == NULL);
  892. args[1] = (PyObject *)code;
  893. int offset = (int)(instr - _PyCode_CODE(code));
  894. /* Offset visible to user should be the offset in bytes, as that is the
  895. * convention for APIs involving code offsets. */
  896. int bytes_offset = offset * (int)sizeof(_Py_CODEUNIT);
  897. PyObject *offset_obj = PyLong_FromSsize_t(bytes_offset);
  898. if (offset_obj == NULL) {
  899. return -1;
  900. }
  901. assert(args[2] == NULL);
  902. args[2] = offset_obj;
  903. PyInterpreterState *interp = tstate->interp;
  904. uint8_t tools = get_tools_for_instruction(code, interp, offset, event);
  905. Py_ssize_t nargsf = nargs | PY_VECTORCALL_ARGUMENTS_OFFSET;
  906. PyObject **callargs = &args[1];
  907. int err = 0;
  908. while (tools) {
  909. int tool = most_significant_bit(tools);
  910. assert(tool >= 0 && tool < 8);
  911. assert(tools & (1 << tool));
  912. tools ^= (1 << tool);
  913. int res = call_one_instrument(interp, tstate, callargs, nargsf, tool, event);
  914. if (res == 0) {
  915. /* Nothing to do */
  916. }
  917. else if (res < 0) {
  918. /* error */
  919. err = -1;
  920. break;
  921. }
  922. else {
  923. /* DISABLE */
  924. if (!PY_MONITORING_IS_INSTRUMENTED_EVENT(event)) {
  925. PyErr_Format(PyExc_ValueError,
  926. "Cannot disable %s events. Callback removed.",
  927. event_names[event]);
  928. /* Clear tool to prevent infinite loop */
  929. Py_CLEAR(interp->monitoring_callables[tool][event]);
  930. err = -1;
  931. break;
  932. }
  933. else {
  934. remove_tools(code, offset, event, 1 << tool);
  935. }
  936. }
  937. }
  938. Py_DECREF(offset_obj);
  939. return err;
  940. }
  941. int
  942. _Py_call_instrumentation(
  943. PyThreadState *tstate, int event,
  944. _PyInterpreterFrame *frame, _Py_CODEUNIT *instr)
  945. {
  946. PyObject *args[3] = { NULL, NULL, NULL };
  947. return call_instrumentation_vector(tstate, event, frame, instr, 2, args);
  948. }
  949. int
  950. _Py_call_instrumentation_arg(
  951. PyThreadState *tstate, int event,
  952. _PyInterpreterFrame *frame, _Py_CODEUNIT *instr, PyObject *arg)
  953. {
  954. PyObject *args[4] = { NULL, NULL, NULL, arg };
  955. return call_instrumentation_vector(tstate, event, frame, instr, 3, args);
  956. }
  957. int
  958. _Py_call_instrumentation_2args(
  959. PyThreadState *tstate, int event,
  960. _PyInterpreterFrame *frame, _Py_CODEUNIT *instr, PyObject *arg0, PyObject *arg1)
  961. {
  962. PyObject *args[5] = { NULL, NULL, NULL, arg0, arg1 };
  963. return call_instrumentation_vector(tstate, event, frame, instr, 4, args);
  964. }
  965. _Py_CODEUNIT *
  966. _Py_call_instrumentation_jump(
  967. PyThreadState *tstate, int event,
  968. _PyInterpreterFrame *frame, _Py_CODEUNIT *instr, _Py_CODEUNIT *target)
  969. {
  970. assert(event == PY_MONITORING_EVENT_JUMP ||
  971. event == PY_MONITORING_EVENT_BRANCH);
  972. assert(frame->prev_instr == instr);
  973. /* Event should occur after the jump */
  974. frame->prev_instr = target;
  975. PyCodeObject *code = frame->f_code;
  976. int to = (int)(target - _PyCode_CODE(code));
  977. PyObject *to_obj = PyLong_FromLong(to * (int)sizeof(_Py_CODEUNIT));
  978. if (to_obj == NULL) {
  979. return NULL;
  980. }
  981. PyObject *args[4] = { NULL, NULL, NULL, to_obj };
  982. int err = call_instrumentation_vector(tstate, event, frame, instr, 3, args);
  983. Py_DECREF(to_obj);
  984. if (err) {
  985. return NULL;
  986. }
  987. if (frame->prev_instr != target) {
  988. /* The callback has caused a jump (by setting the line number) */
  989. return frame->prev_instr;
  990. }
  991. /* Reset prev_instr for INSTRUMENTED_LINE */
  992. frame->prev_instr = instr;
  993. return target;
  994. }
  995. static void
  996. call_instrumentation_vector_protected(
  997. PyThreadState *tstate, int event,
  998. _PyInterpreterFrame *frame, _Py_CODEUNIT *instr, Py_ssize_t nargs, PyObject *args[])
  999. {
  1000. assert(_PyErr_Occurred(tstate));
  1001. PyObject *exc = _PyErr_GetRaisedException(tstate);
  1002. int err = call_instrumentation_vector(tstate, event, frame, instr, nargs, args);
  1003. if (err) {
  1004. Py_XDECREF(exc);
  1005. }
  1006. else {
  1007. _PyErr_SetRaisedException(tstate, exc);
  1008. }
  1009. assert(_PyErr_Occurred(tstate));
  1010. }
  1011. void
  1012. _Py_call_instrumentation_exc2(
  1013. PyThreadState *tstate, int event,
  1014. _PyInterpreterFrame *frame, _Py_CODEUNIT *instr, PyObject *arg0, PyObject *arg1)
  1015. {
  1016. assert(_PyErr_Occurred(tstate));
  1017. PyObject *args[5] = { NULL, NULL, NULL, arg0, arg1 };
  1018. call_instrumentation_vector_protected(tstate, event, frame, instr, 4, args);
  1019. }
  1020. int
  1021. _Py_Instrumentation_GetLine(PyCodeObject *code, int index)
  1022. {
  1023. _PyCoMonitoringData *monitoring = code->_co_monitoring;
  1024. assert(monitoring != NULL);
  1025. assert(monitoring->lines != NULL);
  1026. assert(index >= code->_co_firsttraceable);
  1027. assert(index < Py_SIZE(code));
  1028. _PyCoLineInstrumentationData *line_data = &monitoring->lines[index];
  1029. int8_t line_delta = line_data->line_delta;
  1030. int line = compute_line(code, index, line_delta);
  1031. return line;
  1032. }
  1033. int
  1034. _Py_call_instrumentation_line(PyThreadState *tstate, _PyInterpreterFrame* frame, _Py_CODEUNIT *instr, _Py_CODEUNIT *prev)
  1035. {
  1036. frame->prev_instr = instr;
  1037. PyCodeObject *code = frame->f_code;
  1038. assert(is_version_up_to_date(code, tstate->interp));
  1039. assert(instrumentation_cross_checks(tstate->interp, code));
  1040. int i = (int)(instr - _PyCode_CODE(code));
  1041. _PyCoMonitoringData *monitoring = code->_co_monitoring;
  1042. _PyCoLineInstrumentationData *line_data = &monitoring->lines[i];
  1043. if (tstate->tracing) {
  1044. goto done;
  1045. }
  1046. PyInterpreterState *interp = tstate->interp;
  1047. int8_t line_delta = line_data->line_delta;
  1048. int line = compute_line(code, i, line_delta);
  1049. assert(line >= 0);
  1050. int prev_index = (int)(prev - _PyCode_CODE(code));
  1051. int prev_line = _Py_Instrumentation_GetLine(code, prev_index);
  1052. if (prev_line == line) {
  1053. int prev_opcode = _PyCode_CODE(code)[prev_index].op.code;
  1054. /* RESUME and INSTRUMENTED_RESUME are needed for the operation of
  1055. * instrumentation, so must never be hidden by an INSTRUMENTED_LINE.
  1056. */
  1057. if (prev_opcode != RESUME && prev_opcode != INSTRUMENTED_RESUME) {
  1058. goto done;
  1059. }
  1060. }
  1061. uint8_t tools = code->_co_monitoring->line_tools != NULL ?
  1062. code->_co_monitoring->line_tools[i] :
  1063. (interp->monitors.tools[PY_MONITORING_EVENT_LINE] |
  1064. code->_co_monitoring->local_monitors.tools[PY_MONITORING_EVENT_LINE]
  1065. );
  1066. PyObject *line_obj = PyLong_FromSsize_t(line);
  1067. if (line_obj == NULL) {
  1068. return -1;
  1069. }
  1070. PyObject *args[3] = { NULL, (PyObject *)code, line_obj };
  1071. while (tools) {
  1072. int tool = most_significant_bit(tools);
  1073. assert(tool >= 0 && tool < 8);
  1074. assert(tools & (1 << tool));
  1075. tools &= ~(1 << tool);
  1076. int res = call_one_instrument(interp, tstate, &args[1],
  1077. 2 | PY_VECTORCALL_ARGUMENTS_OFFSET,
  1078. tool, PY_MONITORING_EVENT_LINE);
  1079. if (res == 0) {
  1080. /* Nothing to do */
  1081. }
  1082. else if (res < 0) {
  1083. /* error */
  1084. Py_DECREF(line_obj);
  1085. return -1;
  1086. }
  1087. else {
  1088. /* DISABLE */
  1089. remove_line_tools(code, i, 1 << tool);
  1090. }
  1091. }
  1092. Py_DECREF(line_obj);
  1093. uint8_t original_opcode;
  1094. done:
  1095. original_opcode = line_data->original_opcode;
  1096. assert(original_opcode != 0);
  1097. assert(original_opcode < INSTRUMENTED_LINE);
  1098. assert(_PyOpcode_Deopt[original_opcode] == original_opcode);
  1099. return original_opcode;
  1100. }
  1101. int
  1102. _Py_call_instrumentation_instruction(PyThreadState *tstate, _PyInterpreterFrame* frame, _Py_CODEUNIT *instr)
  1103. {
  1104. PyCodeObject *code = frame->f_code;
  1105. assert(is_version_up_to_date(code, tstate->interp));
  1106. assert(instrumentation_cross_checks(tstate->interp, code));
  1107. int offset = (int)(instr - _PyCode_CODE(code));
  1108. _PyCoMonitoringData *instrumentation_data = code->_co_monitoring;
  1109. assert(instrumentation_data->per_instruction_opcodes);
  1110. int next_opcode = instrumentation_data->per_instruction_opcodes[offset];
  1111. if (tstate->tracing) {
  1112. return next_opcode;
  1113. }
  1114. PyInterpreterState *interp = tstate->interp;
  1115. uint8_t tools = instrumentation_data->per_instruction_tools != NULL ?
  1116. instrumentation_data->per_instruction_tools[offset] :
  1117. (interp->monitors.tools[PY_MONITORING_EVENT_INSTRUCTION] |
  1118. code->_co_monitoring->local_monitors.tools[PY_MONITORING_EVENT_INSTRUCTION]
  1119. );
  1120. int bytes_offset = offset * (int)sizeof(_Py_CODEUNIT);
  1121. PyObject *offset_obj = PyLong_FromSsize_t(bytes_offset);
  1122. if (offset_obj == NULL) {
  1123. return -1;
  1124. }
  1125. PyObject *args[3] = { NULL, (PyObject *)code, offset_obj };
  1126. while (tools) {
  1127. int tool = most_significant_bit(tools);
  1128. assert(tool >= 0 && tool < 8);
  1129. assert(tools & (1 << tool));
  1130. tools &= ~(1 << tool);
  1131. int res = call_one_instrument(interp, tstate, &args[1],
  1132. 2 | PY_VECTORCALL_ARGUMENTS_OFFSET,
  1133. tool, PY_MONITORING_EVENT_INSTRUCTION);
  1134. if (res == 0) {
  1135. /* Nothing to do */
  1136. }
  1137. else if (res < 0) {
  1138. /* error */
  1139. Py_DECREF(offset_obj);
  1140. return -1;
  1141. }
  1142. else {
  1143. /* DISABLE */
  1144. remove_per_instruction_tools(code, offset, 1 << tool);
  1145. }
  1146. }
  1147. Py_DECREF(offset_obj);
  1148. assert(next_opcode != 0);
  1149. return next_opcode;
  1150. }
  1151. PyObject *
  1152. _PyMonitoring_RegisterCallback(int tool_id, int event_id, PyObject *obj)
  1153. {
  1154. PyInterpreterState *is = _PyInterpreterState_Get();
  1155. assert(0 <= tool_id && tool_id < PY_MONITORING_TOOL_IDS);
  1156. assert(0 <= event_id && event_id < _PY_MONITORING_EVENTS);
  1157. PyObject *callback = is->monitoring_callables[tool_id][event_id];
  1158. is->monitoring_callables[tool_id][event_id] = Py_XNewRef(obj);
  1159. return callback;
  1160. }
  1161. static void
  1162. initialize_tools(PyCodeObject *code)
  1163. {
  1164. uint8_t* tools = code->_co_monitoring->tools;
  1165. assert(tools != NULL);
  1166. int code_len = (int)Py_SIZE(code);
  1167. for (int i = 0; i < code_len; i++) {
  1168. _Py_CODEUNIT *instr = &_PyCode_CODE(code)[i];
  1169. int opcode = instr->op.code;
  1170. if (opcode == INSTRUMENTED_LINE) {
  1171. opcode = code->_co_monitoring->lines[i].original_opcode;
  1172. }
  1173. if (opcode == INSTRUMENTED_INSTRUCTION) {
  1174. opcode = code->_co_monitoring->per_instruction_opcodes[i];
  1175. }
  1176. bool instrumented = is_instrumented(opcode);
  1177. if (instrumented) {
  1178. opcode = DE_INSTRUMENT[opcode];
  1179. assert(opcode != 0);
  1180. }
  1181. opcode = _PyOpcode_Deopt[opcode];
  1182. if (opcode_has_event(opcode)) {
  1183. if (instrumented) {
  1184. int8_t event;
  1185. if (opcode == RESUME) {
  1186. event = instr->op.arg != 0;
  1187. }
  1188. else {
  1189. event = EVENT_FOR_OPCODE[opcode];
  1190. assert(event > 0);
  1191. }
  1192. assert(event >= 0);
  1193. assert(PY_MONITORING_IS_INSTRUMENTED_EVENT(event));
  1194. tools[i] = code->_co_monitoring->active_monitors.tools[event];
  1195. CHECK(tools[i] != 0);
  1196. }
  1197. else {
  1198. tools[i] = 0;
  1199. }
  1200. }
  1201. #ifdef Py_DEBUG
  1202. /* Initialize tools for invalid locations to all ones to try to catch errors */
  1203. else {
  1204. tools[i] = 0xff;
  1205. }
  1206. for (int j = 1; j <= _PyOpcode_Caches[opcode]; j++) {
  1207. tools[i+j] = 0xff;
  1208. }
  1209. #endif
  1210. i += _PyOpcode_Caches[opcode];
  1211. }
  1212. }
  1213. #define NO_LINE -128
  1214. static void
  1215. initialize_lines(PyCodeObject *code)
  1216. {
  1217. _PyCoLineInstrumentationData *line_data = code->_co_monitoring->lines;
  1218. assert(line_data != NULL);
  1219. int code_len = (int)Py_SIZE(code);
  1220. PyCodeAddressRange range;
  1221. _PyCode_InitAddressRange(code, &range);
  1222. for (int i = 0; i < code->_co_firsttraceable && i < code_len; i++) {
  1223. line_data[i].original_opcode = 0;
  1224. line_data[i].line_delta = -127;
  1225. }
  1226. int current_line = -1;
  1227. for (int i = code->_co_firsttraceable; i < code_len; ) {
  1228. int opcode = _Py_GetBaseOpcode(code, i);
  1229. int line = _PyCode_CheckLineNumber(i*(int)sizeof(_Py_CODEUNIT), &range);
  1230. line_data[i].line_delta = compute_line_delta(code, i, line);
  1231. int length = instruction_length(code, i);
  1232. switch (opcode) {
  1233. case END_ASYNC_FOR:
  1234. case END_FOR:
  1235. case END_SEND:
  1236. case RESUME:
  1237. /* END_FOR cannot start a line, as it is skipped by FOR_ITER
  1238. * END_SEND cannot start a line, as it is skipped by SEND
  1239. * RESUME must not be instrumented with INSTRUMENT_LINE */
  1240. line_data[i].original_opcode = 0;
  1241. break;
  1242. default:
  1243. /* Set original_opcode to the opcode iff the instruction
  1244. * starts a line, and thus should be instrumented.
  1245. * This saves having to perform this check every time the
  1246. * we turn instrumentation on or off, and serves as a sanity
  1247. * check when debugging.
  1248. */
  1249. if (line != current_line && line >= 0) {
  1250. line_data[i].original_opcode = opcode;
  1251. }
  1252. else {
  1253. line_data[i].original_opcode = 0;
  1254. }
  1255. current_line = line;
  1256. }
  1257. for (int j = 1; j < length; j++) {
  1258. line_data[i+j].original_opcode = 0;
  1259. line_data[i+j].line_delta = NO_LINE;
  1260. }
  1261. i += length;
  1262. }
  1263. for (int i = code->_co_firsttraceable; i < code_len; ) {
  1264. int opcode = _Py_GetBaseOpcode(code, i);
  1265. int oparg = 0;
  1266. while (opcode == EXTENDED_ARG) {
  1267. oparg = (oparg << 8) | _PyCode_CODE(code)[i].op.arg;
  1268. i++;
  1269. opcode = _Py_GetBaseOpcode(code, i);
  1270. }
  1271. oparg = (oparg << 8) | _PyCode_CODE(code)[i].op.arg;
  1272. i += instruction_length(code, i);
  1273. int target = -1;
  1274. switch (opcode) {
  1275. case POP_JUMP_IF_FALSE:
  1276. case POP_JUMP_IF_TRUE:
  1277. case POP_JUMP_IF_NONE:
  1278. case POP_JUMP_IF_NOT_NONE:
  1279. case JUMP_FORWARD:
  1280. {
  1281. target = i + oparg;
  1282. break;
  1283. }
  1284. case FOR_ITER:
  1285. case SEND:
  1286. {
  1287. /* Skip over END_FOR/END_SEND */
  1288. target = i + oparg + 1;
  1289. break;
  1290. }
  1291. case JUMP_BACKWARD:
  1292. case JUMP_BACKWARD_NO_INTERRUPT:
  1293. {
  1294. target = i - oparg;
  1295. break;
  1296. }
  1297. default:
  1298. continue;
  1299. }
  1300. assert(target >= 0);
  1301. if (line_data[target].line_delta != NO_LINE) {
  1302. line_data[target].original_opcode = _Py_GetBaseOpcode(code, target);
  1303. }
  1304. }
  1305. /* Scan exception table */
  1306. unsigned char *start = (unsigned char *)PyBytes_AS_STRING(code->co_exceptiontable);
  1307. unsigned char *end = start + PyBytes_GET_SIZE(code->co_exceptiontable);
  1308. unsigned char *scan = start;
  1309. while (scan < end) {
  1310. int start_offset, size, handler;
  1311. scan = parse_varint(scan, &start_offset);
  1312. assert(start_offset >= 0 && start_offset < code_len);
  1313. scan = parse_varint(scan, &size);
  1314. assert(size >= 0 && start_offset+size <= code_len);
  1315. scan = parse_varint(scan, &handler);
  1316. assert(handler >= 0 && handler < code_len);
  1317. int depth_and_lasti;
  1318. scan = parse_varint(scan, &depth_and_lasti);
  1319. int original_opcode = _Py_GetBaseOpcode(code, handler);
  1320. /* Skip if not the start of a line.
  1321. * END_ASYNC_FOR is a bit special as it marks the end of
  1322. * an `async for` loop, which should not generate its own
  1323. * line event. */
  1324. if (line_data[handler].line_delta != NO_LINE &&
  1325. original_opcode != END_ASYNC_FOR) {
  1326. line_data[handler].original_opcode = original_opcode;
  1327. }
  1328. }
  1329. }
  1330. static void
  1331. initialize_line_tools(PyCodeObject *code, _Py_LocalMonitors *all_events)
  1332. {
  1333. uint8_t *line_tools = code->_co_monitoring->line_tools;
  1334. assert(line_tools != NULL);
  1335. int code_len = (int)Py_SIZE(code);
  1336. for (int i = 0; i < code_len; i++) {
  1337. line_tools[i] = all_events->tools[PY_MONITORING_EVENT_LINE];
  1338. }
  1339. }
  1340. static int
  1341. allocate_instrumentation_data(PyCodeObject *code)
  1342. {
  1343. if (code->_co_monitoring == NULL) {
  1344. code->_co_monitoring = PyMem_Malloc(sizeof(_PyCoMonitoringData));
  1345. if (code->_co_monitoring == NULL) {
  1346. PyErr_NoMemory();
  1347. return -1;
  1348. }
  1349. code->_co_monitoring->local_monitors = (_Py_LocalMonitors){ 0 };
  1350. code->_co_monitoring->active_monitors = (_Py_LocalMonitors){ 0 };
  1351. code->_co_monitoring->tools = NULL;
  1352. code->_co_monitoring->lines = NULL;
  1353. code->_co_monitoring->line_tools = NULL;
  1354. code->_co_monitoring->per_instruction_opcodes = NULL;
  1355. code->_co_monitoring->per_instruction_tools = NULL;
  1356. }
  1357. return 0;
  1358. }
  1359. static int
  1360. update_instrumentation_data(PyCodeObject *code, PyInterpreterState *interp)
  1361. {
  1362. int code_len = (int)Py_SIZE(code);
  1363. if (allocate_instrumentation_data(code)) {
  1364. return -1;
  1365. }
  1366. _Py_LocalMonitors all_events = local_union(
  1367. interp->monitors,
  1368. code->_co_monitoring->local_monitors);
  1369. bool multitools = multiple_tools(&all_events);
  1370. if (code->_co_monitoring->tools == NULL && multitools) {
  1371. code->_co_monitoring->tools = PyMem_Malloc(code_len);
  1372. if (code->_co_monitoring->tools == NULL) {
  1373. PyErr_NoMemory();
  1374. return -1;
  1375. }
  1376. initialize_tools(code);
  1377. }
  1378. if (all_events.tools[PY_MONITORING_EVENT_LINE]) {
  1379. if (code->_co_monitoring->lines == NULL) {
  1380. code->_co_monitoring->lines = PyMem_Malloc(code_len * sizeof(_PyCoLineInstrumentationData));
  1381. if (code->_co_monitoring->lines == NULL) {
  1382. PyErr_NoMemory();
  1383. return -1;
  1384. }
  1385. initialize_lines(code);
  1386. }
  1387. if (multitools && code->_co_monitoring->line_tools == NULL) {
  1388. code->_co_monitoring->line_tools = PyMem_Malloc(code_len);
  1389. if (code->_co_monitoring->line_tools == NULL) {
  1390. PyErr_NoMemory();
  1391. return -1;
  1392. }
  1393. initialize_line_tools(code, &all_events);
  1394. }
  1395. }
  1396. if (all_events.tools[PY_MONITORING_EVENT_INSTRUCTION]) {
  1397. if (code->_co_monitoring->per_instruction_opcodes == NULL) {
  1398. code->_co_monitoring->per_instruction_opcodes = PyMem_Malloc(code_len * sizeof(_PyCoLineInstrumentationData));
  1399. if (code->_co_monitoring->per_instruction_opcodes == NULL) {
  1400. PyErr_NoMemory();
  1401. return -1;
  1402. }
  1403. /* This may not be necessary, as we can initialize this memory lazily, but it helps catch errors. */
  1404. for (int i = 0; i < code_len; i++) {
  1405. code->_co_monitoring->per_instruction_opcodes[i] = 0;
  1406. }
  1407. }
  1408. if (multitools && code->_co_monitoring->per_instruction_tools == NULL) {
  1409. code->_co_monitoring->per_instruction_tools = PyMem_Malloc(code_len);
  1410. if (code->_co_monitoring->per_instruction_tools == NULL) {
  1411. PyErr_NoMemory();
  1412. return -1;
  1413. }
  1414. /* This may not be necessary, as we can initialize this memory lazily, but it helps catch errors. */
  1415. for (int i = 0; i < code_len; i++) {
  1416. code->_co_monitoring->per_instruction_tools[i] = 0;
  1417. }
  1418. }
  1419. }
  1420. return 0;
  1421. }
  1422. static const uint8_t super_instructions[256] = {
  1423. [LOAD_FAST__LOAD_FAST] = 1,
  1424. [LOAD_FAST__LOAD_CONST] = 1,
  1425. [STORE_FAST__LOAD_FAST] = 1,
  1426. [STORE_FAST__STORE_FAST] = 1,
  1427. [LOAD_CONST__LOAD_FAST] = 1,
  1428. };
  1429. /* Should use instruction metadata for this */
  1430. static bool
  1431. is_super_instruction(uint8_t opcode) {
  1432. return super_instructions[opcode] != 0;
  1433. }
  1434. int
  1435. _Py_Instrument(PyCodeObject *code, PyInterpreterState *interp)
  1436. {
  1437. if (is_version_up_to_date(code, interp)) {
  1438. assert(
  1439. interp->monitoring_version == 0 ||
  1440. instrumentation_cross_checks(interp, code)
  1441. );
  1442. return 0;
  1443. }
  1444. int code_len = (int)Py_SIZE(code);
  1445. /* code->_co_firsttraceable >= code_len indicates
  1446. * that no instrumentation can be inserted.
  1447. * Exit early to avoid creating instrumentation
  1448. * data for potential statically allocated code
  1449. * objects.
  1450. * See https://github.com/python/cpython/issues/108390 */
  1451. if (code->_co_firsttraceable >= code_len) {
  1452. return 0;
  1453. }
  1454. if (update_instrumentation_data(code, interp)) {
  1455. return -1;
  1456. }
  1457. _Py_LocalMonitors active_events = local_union(
  1458. interp->monitors,
  1459. code->_co_monitoring->local_monitors);
  1460. _Py_LocalMonitors new_events;
  1461. _Py_LocalMonitors removed_events;
  1462. bool restarted = interp->last_restart_version > code->_co_instrumentation_version;
  1463. if (restarted) {
  1464. removed_events = code->_co_monitoring->active_monitors;
  1465. new_events = active_events;
  1466. }
  1467. else {
  1468. removed_events = monitors_sub(code->_co_monitoring->active_monitors, active_events);
  1469. new_events = monitors_sub(active_events, code->_co_monitoring->active_monitors);
  1470. assert(monitors_are_empty(monitors_and(new_events, removed_events)));
  1471. }
  1472. code->_co_monitoring->active_monitors = active_events;
  1473. code->_co_instrumentation_version = interp->monitoring_version;
  1474. if (monitors_are_empty(new_events) && monitors_are_empty(removed_events)) {
  1475. #ifdef INSTRUMENT_DEBUG
  1476. sanity_check_instrumentation(code);
  1477. #endif
  1478. return 0;
  1479. }
  1480. /* Insert instrumentation */
  1481. for (int i = 0; i < code_len; i+= instruction_length(code, i)) {
  1482. _Py_CODEUNIT *instr = &_PyCode_CODE(code)[i];
  1483. if (is_super_instruction(instr->op.code)) {
  1484. instr->op.code = _PyOpcode_Deopt[instr->op.code];
  1485. }
  1486. CHECK(instr->op.code != 0);
  1487. int base_opcode = _Py_GetBaseOpcode(code, i);
  1488. if (opcode_has_event(base_opcode)) {
  1489. int8_t event;
  1490. if (base_opcode == RESUME) {
  1491. event = instr->op.arg > 0;
  1492. }
  1493. else {
  1494. event = EVENT_FOR_OPCODE[base_opcode];
  1495. assert(event > 0);
  1496. }
  1497. uint8_t removed_tools = removed_events.tools[event];
  1498. if (removed_tools) {
  1499. remove_tools(code, i, event, removed_tools);
  1500. }
  1501. uint8_t new_tools = new_events.tools[event];
  1502. if (new_tools) {
  1503. add_tools(code, i, event, new_tools);
  1504. }
  1505. }
  1506. }
  1507. // GH-103845: We need to remove both the line and instruction instrumentation before
  1508. // adding new ones, otherwise we may remove the newly added instrumentation.
  1509. uint8_t removed_line_tools = removed_events.tools[PY_MONITORING_EVENT_LINE];
  1510. uint8_t removed_per_instruction_tools = removed_events.tools[PY_MONITORING_EVENT_INSTRUCTION];
  1511. if (removed_line_tools) {
  1512. _PyCoLineInstrumentationData *line_data = code->_co_monitoring->lines;
  1513. for (int i = code->_co_firsttraceable; i < code_len;) {
  1514. if (line_data[i].original_opcode) {
  1515. if (removed_line_tools) {
  1516. remove_line_tools(code, i, removed_line_tools);
  1517. }
  1518. }
  1519. i += instruction_length(code, i);
  1520. }
  1521. }
  1522. if (removed_per_instruction_tools) {
  1523. for (int i = code->_co_firsttraceable; i < code_len;) {
  1524. int opcode = _Py_GetBaseOpcode(code, i);
  1525. if (opcode == RESUME || opcode == END_FOR) {
  1526. i += instruction_length(code, i);
  1527. continue;
  1528. }
  1529. if (removed_per_instruction_tools) {
  1530. remove_per_instruction_tools(code, i, removed_per_instruction_tools);
  1531. }
  1532. i += instruction_length(code, i);
  1533. }
  1534. }
  1535. #ifdef INSTRUMENT_DEBUG
  1536. sanity_check_instrumentation(code);
  1537. #endif
  1538. uint8_t new_line_tools = new_events.tools[PY_MONITORING_EVENT_LINE];
  1539. uint8_t new_per_instruction_tools = new_events.tools[PY_MONITORING_EVENT_INSTRUCTION];
  1540. if (new_line_tools) {
  1541. _PyCoLineInstrumentationData *line_data = code->_co_monitoring->lines;
  1542. for (int i = code->_co_firsttraceable; i < code_len;) {
  1543. if (line_data[i].original_opcode) {
  1544. if (new_line_tools) {
  1545. add_line_tools(code, i, new_line_tools);
  1546. }
  1547. }
  1548. i += instruction_length(code, i);
  1549. }
  1550. }
  1551. if (new_per_instruction_tools) {
  1552. for (int i = code->_co_firsttraceable; i < code_len;) {
  1553. int opcode = _Py_GetBaseOpcode(code, i);
  1554. if (opcode == RESUME || opcode == END_FOR) {
  1555. i += instruction_length(code, i);
  1556. continue;
  1557. }
  1558. if (new_per_instruction_tools) {
  1559. add_per_instruction_tools(code, i, new_per_instruction_tools);
  1560. }
  1561. i += instruction_length(code, i);
  1562. }
  1563. }
  1564. #ifdef INSTRUMENT_DEBUG
  1565. sanity_check_instrumentation(code);
  1566. #endif
  1567. return 0;
  1568. }
  1569. #define C_RETURN_EVENTS \
  1570. ((1 << PY_MONITORING_EVENT_C_RETURN) | \
  1571. (1 << PY_MONITORING_EVENT_C_RAISE))
  1572. #define C_CALL_EVENTS \
  1573. (C_RETURN_EVENTS | (1 << PY_MONITORING_EVENT_CALL))
  1574. static int
  1575. instrument_all_executing_code_objects(PyInterpreterState *interp) {
  1576. _PyRuntimeState *runtime = &_PyRuntime;
  1577. HEAD_LOCK(runtime);
  1578. PyThreadState* ts = PyInterpreterState_ThreadHead(interp);
  1579. HEAD_UNLOCK(runtime);
  1580. while (ts) {
  1581. _PyInterpreterFrame *frame = ts->cframe->current_frame;
  1582. while (frame) {
  1583. if (frame->owner != FRAME_OWNED_BY_CSTACK) {
  1584. if (_Py_Instrument(frame->f_code, interp)) {
  1585. return -1;
  1586. }
  1587. }
  1588. frame = frame->previous;
  1589. }
  1590. HEAD_LOCK(runtime);
  1591. ts = PyThreadState_Next(ts);
  1592. HEAD_UNLOCK(runtime);
  1593. }
  1594. return 0;
  1595. }
  1596. static void
  1597. set_events(_Py_GlobalMonitors *m, int tool_id, _PyMonitoringEventSet events)
  1598. {
  1599. assert(0 <= tool_id && tool_id < PY_MONITORING_TOOL_IDS);
  1600. for (int e = 0; e < _PY_MONITORING_UNGROUPED_EVENTS; e++) {
  1601. uint8_t *tools = &m->tools[e];
  1602. int active = (events >> e) & 1;
  1603. *tools &= ~(1 << tool_id);
  1604. *tools |= (active << tool_id);
  1605. }
  1606. }
  1607. static void
  1608. set_local_events(_Py_LocalMonitors *m, int tool_id, _PyMonitoringEventSet events)
  1609. {
  1610. assert(0 <= tool_id && tool_id < PY_MONITORING_TOOL_IDS);
  1611. for (int e = 0; e < _PY_MONITORING_LOCAL_EVENTS; e++) {
  1612. uint8_t *tools = &m->tools[e];
  1613. int val = (events >> e) & 1;
  1614. *tools &= ~(1 << tool_id);
  1615. *tools |= (val << tool_id);
  1616. }
  1617. }
  1618. static int
  1619. check_tool(PyInterpreterState *interp, int tool_id)
  1620. {
  1621. if (tool_id < PY_MONITORING_SYS_PROFILE_ID &&
  1622. interp->monitoring_tool_names[tool_id] == NULL)
  1623. {
  1624. PyErr_Format(PyExc_ValueError, "tool %d is not in use", tool_id);
  1625. return -1;
  1626. }
  1627. return 0;
  1628. }
  1629. int
  1630. _PyMonitoring_SetEvents(int tool_id, _PyMonitoringEventSet events)
  1631. {
  1632. assert(0 <= tool_id && tool_id < PY_MONITORING_TOOL_IDS);
  1633. PyInterpreterState *interp = _PyInterpreterState_Get();
  1634. assert(events < (1 << _PY_MONITORING_UNGROUPED_EVENTS));
  1635. if (check_tool(interp, tool_id)) {
  1636. return -1;
  1637. }
  1638. uint32_t existing_events = get_events(&interp->monitors, tool_id);
  1639. if (existing_events == events) {
  1640. return 0;
  1641. }
  1642. set_events(&interp->monitors, tool_id, events);
  1643. interp->monitoring_version++;
  1644. return instrument_all_executing_code_objects(interp);
  1645. }
  1646. int
  1647. _PyMonitoring_SetLocalEvents(PyCodeObject *code, int tool_id, _PyMonitoringEventSet events)
  1648. {
  1649. assert(0 <= tool_id && tool_id < PY_MONITORING_TOOL_IDS);
  1650. PyInterpreterState *interp = _PyInterpreterState_Get();
  1651. assert(events < (1 << _PY_MONITORING_LOCAL_EVENTS));
  1652. if (code->_co_firsttraceable >= Py_SIZE(code)) {
  1653. PyErr_Format(PyExc_SystemError, "cannot instrument shim code object '%U'", code->co_name);
  1654. return -1;
  1655. }
  1656. if (check_tool(interp, tool_id)) {
  1657. return -1;
  1658. }
  1659. if (allocate_instrumentation_data(code)) {
  1660. return -1;
  1661. }
  1662. _Py_LocalMonitors *local = &code->_co_monitoring->local_monitors;
  1663. uint32_t existing_events = get_local_events(local, tool_id);
  1664. if (existing_events == events) {
  1665. return 0;
  1666. }
  1667. set_local_events(local, tool_id, events);
  1668. if (is_version_up_to_date(code, interp)) {
  1669. /* Force instrumentation update */
  1670. code->_co_instrumentation_version = UINT64_MAX;
  1671. }
  1672. if (_Py_Instrument(code, interp)) {
  1673. return -1;
  1674. }
  1675. return 0;
  1676. }
  1677. /*[clinic input]
  1678. module monitoring
  1679. [clinic start generated code]*/
  1680. /*[clinic end generated code: output=da39a3ee5e6b4b0d input=37257f5987a360cf]*/
  1681. /*[clinic end generated code]*/
  1682. #include "clinic/instrumentation.c.h"
  1683. static int
  1684. check_valid_tool(int tool_id)
  1685. {
  1686. if (tool_id < 0 || tool_id >= PY_MONITORING_SYS_PROFILE_ID) {
  1687. PyErr_Format(PyExc_ValueError, "invalid tool %d (must be between 0 and 5)", tool_id);
  1688. return -1;
  1689. }
  1690. return 0;
  1691. }
  1692. /*[clinic input]
  1693. monitoring.use_tool_id
  1694. tool_id: int
  1695. name: object
  1696. /
  1697. [clinic start generated code]*/
  1698. static PyObject *
  1699. monitoring_use_tool_id_impl(PyObject *module, int tool_id, PyObject *name)
  1700. /*[clinic end generated code: output=30d76dc92b7cd653 input=ebc453761c621be1]*/
  1701. {
  1702. if (check_valid_tool(tool_id)) {
  1703. return NULL;
  1704. }
  1705. if (!PyUnicode_Check(name)) {
  1706. PyErr_SetString(PyExc_ValueError, "tool name must be a str");
  1707. return NULL;
  1708. }
  1709. PyInterpreterState *interp = _PyInterpreterState_Get();
  1710. if (interp->monitoring_tool_names[tool_id] != NULL) {
  1711. PyErr_Format(PyExc_ValueError, "tool %d is already in use", tool_id);
  1712. return NULL;
  1713. }
  1714. interp->monitoring_tool_names[tool_id] = Py_NewRef(name);
  1715. Py_RETURN_NONE;
  1716. }
  1717. /*[clinic input]
  1718. monitoring.free_tool_id
  1719. tool_id: int
  1720. /
  1721. [clinic start generated code]*/
  1722. static PyObject *
  1723. monitoring_free_tool_id_impl(PyObject *module, int tool_id)
  1724. /*[clinic end generated code: output=86c2d2a1219a8591 input=a23fb6be3a8618e9]*/
  1725. {
  1726. if (check_valid_tool(tool_id)) {
  1727. return NULL;
  1728. }
  1729. PyInterpreterState *interp = _PyInterpreterState_Get();
  1730. Py_CLEAR(interp->monitoring_tool_names[tool_id]);
  1731. Py_RETURN_NONE;
  1732. }
  1733. /*[clinic input]
  1734. monitoring.get_tool
  1735. tool_id: int
  1736. /
  1737. [clinic start generated code]*/
  1738. static PyObject *
  1739. monitoring_get_tool_impl(PyObject *module, int tool_id)
  1740. /*[clinic end generated code: output=1c05a98b404a9a16 input=eeee9bebd0bcae9d]*/
  1741. /*[clinic end generated code]*/
  1742. {
  1743. if (check_valid_tool(tool_id)) {
  1744. return NULL;
  1745. }
  1746. PyInterpreterState *interp = _PyInterpreterState_Get();
  1747. PyObject *name = interp->monitoring_tool_names[tool_id];
  1748. if (name == NULL) {
  1749. Py_RETURN_NONE;
  1750. }
  1751. return Py_NewRef(name);
  1752. }
  1753. /*[clinic input]
  1754. monitoring.register_callback
  1755. tool_id: int
  1756. event: int
  1757. func: object
  1758. /
  1759. [clinic start generated code]*/
  1760. static PyObject *
  1761. monitoring_register_callback_impl(PyObject *module, int tool_id, int event,
  1762. PyObject *func)
  1763. /*[clinic end generated code: output=e64daa363004030c input=df6d70ea4cf81007]*/
  1764. {
  1765. if (check_valid_tool(tool_id)) {
  1766. return NULL;
  1767. }
  1768. if (_Py_popcount32(event) != 1) {
  1769. PyErr_SetString(PyExc_ValueError, "The callback can only be set for one event at a time");
  1770. return NULL;
  1771. }
  1772. int event_id = _Py_bit_length(event)-1;
  1773. if (event_id < 0 || event_id >= _PY_MONITORING_EVENTS) {
  1774. PyErr_Format(PyExc_ValueError, "invalid event %d", event);
  1775. return NULL;
  1776. }
  1777. if (PySys_Audit("sys.monitoring.register_callback", "O", func) < 0) {
  1778. return NULL;
  1779. }
  1780. if (func == Py_None) {
  1781. func = NULL;
  1782. }
  1783. func = _PyMonitoring_RegisterCallback(tool_id, event_id, func);
  1784. if (func == NULL) {
  1785. Py_RETURN_NONE;
  1786. }
  1787. return func;
  1788. }
  1789. /*[clinic input]
  1790. monitoring.get_events -> int
  1791. tool_id: int
  1792. /
  1793. [clinic start generated code]*/
  1794. static int
  1795. monitoring_get_events_impl(PyObject *module, int tool_id)
  1796. /*[clinic end generated code: output=4450cc13f826c8c0 input=a64b238f76c4b2f7]*/
  1797. {
  1798. if (check_valid_tool(tool_id)) {
  1799. return -1;
  1800. }
  1801. _Py_GlobalMonitors *m = &_PyInterpreterState_GET()->monitors;
  1802. _PyMonitoringEventSet event_set = get_events(m, tool_id);
  1803. return event_set;
  1804. }
  1805. /*[clinic input]
  1806. monitoring.set_events
  1807. tool_id: int
  1808. event_set: int
  1809. /
  1810. [clinic start generated code]*/
  1811. static PyObject *
  1812. monitoring_set_events_impl(PyObject *module, int tool_id, int event_set)
  1813. /*[clinic end generated code: output=1916c1e49cfb5bdb input=a77ba729a242142b]*/
  1814. {
  1815. if (check_valid_tool(tool_id)) {
  1816. return NULL;
  1817. }
  1818. if (event_set < 0 || event_set >= (1 << _PY_MONITORING_EVENTS)) {
  1819. PyErr_Format(PyExc_ValueError, "invalid event set 0x%x", event_set);
  1820. return NULL;
  1821. }
  1822. if ((event_set & C_RETURN_EVENTS) && (event_set & C_CALL_EVENTS) != C_CALL_EVENTS) {
  1823. PyErr_Format(PyExc_ValueError, "cannot set C_RETURN or C_RAISE events independently");
  1824. return NULL;
  1825. }
  1826. event_set &= ~C_RETURN_EVENTS;
  1827. if (_PyMonitoring_SetEvents(tool_id, event_set)) {
  1828. return NULL;
  1829. }
  1830. Py_RETURN_NONE;
  1831. }
  1832. /*[clinic input]
  1833. monitoring.get_local_events -> int
  1834. tool_id: int
  1835. code: object
  1836. /
  1837. [clinic start generated code]*/
  1838. static int
  1839. monitoring_get_local_events_impl(PyObject *module, int tool_id,
  1840. PyObject *code)
  1841. /*[clinic end generated code: output=d3e92c1c9c1de8f9 input=bb0f927530386a94]*/
  1842. {
  1843. if (!PyCode_Check(code)) {
  1844. PyErr_Format(
  1845. PyExc_TypeError,
  1846. "code must be a code object"
  1847. );
  1848. return -1;
  1849. }
  1850. if (check_valid_tool(tool_id)) {
  1851. return -1;
  1852. }
  1853. _PyMonitoringEventSet event_set = 0;
  1854. _PyCoMonitoringData *data = ((PyCodeObject *)code)->_co_monitoring;
  1855. if (data != NULL) {
  1856. for (int e = 0; e < _PY_MONITORING_LOCAL_EVENTS; e++) {
  1857. if ((data->local_monitors.tools[e] >> tool_id) & 1) {
  1858. event_set |= (1 << e);
  1859. }
  1860. }
  1861. }
  1862. return event_set;
  1863. }
  1864. /*[clinic input]
  1865. monitoring.set_local_events
  1866. tool_id: int
  1867. code: object
  1868. event_set: int
  1869. /
  1870. [clinic start generated code]*/
  1871. static PyObject *
  1872. monitoring_set_local_events_impl(PyObject *module, int tool_id,
  1873. PyObject *code, int event_set)
  1874. /*[clinic end generated code: output=68cc755a65dfea99 input=5655ecd78d937a29]*/
  1875. {
  1876. if (!PyCode_Check(code)) {
  1877. PyErr_Format(
  1878. PyExc_TypeError,
  1879. "code must be a code object"
  1880. );
  1881. return NULL;
  1882. }
  1883. if (check_valid_tool(tool_id)) {
  1884. return NULL;
  1885. }
  1886. if ((event_set & C_RETURN_EVENTS) && (event_set & C_CALL_EVENTS) != C_CALL_EVENTS) {
  1887. PyErr_Format(PyExc_ValueError, "cannot set C_RETURN or C_RAISE events independently");
  1888. return NULL;
  1889. }
  1890. event_set &= ~C_RETURN_EVENTS;
  1891. if (event_set < 0 || event_set >= (1 << _PY_MONITORING_LOCAL_EVENTS)) {
  1892. PyErr_Format(PyExc_ValueError, "invalid local event set 0x%x", event_set);
  1893. return NULL;
  1894. }
  1895. if (_PyMonitoring_SetLocalEvents((PyCodeObject*)code, tool_id, event_set)) {
  1896. return NULL;
  1897. }
  1898. Py_RETURN_NONE;
  1899. }
  1900. /*[clinic input]
  1901. monitoring.restart_events
  1902. [clinic start generated code]*/
  1903. static PyObject *
  1904. monitoring_restart_events_impl(PyObject *module)
  1905. /*[clinic end generated code: output=e025dd5ba33314c4 input=add8a855063c8008]*/
  1906. {
  1907. /* We want to ensure that:
  1908. * last restart version > instrumented version for all code objects
  1909. * last restart version < current version
  1910. */
  1911. PyInterpreterState *interp = _PyInterpreterState_Get();
  1912. interp->last_restart_version = interp->monitoring_version + 1;
  1913. interp->monitoring_version = interp->last_restart_version + 1;
  1914. if (instrument_all_executing_code_objects(interp)) {
  1915. return NULL;
  1916. }
  1917. Py_RETURN_NONE;
  1918. }
  1919. static int
  1920. add_power2_constant(PyObject *obj, const char *name, int i)
  1921. {
  1922. PyObject *val = PyLong_FromLong(1<<i);
  1923. if (val == NULL) {
  1924. return -1;
  1925. }
  1926. int err = PyObject_SetAttrString(obj, name, val);
  1927. Py_DECREF(val);
  1928. return err;
  1929. }
  1930. /*[clinic input]
  1931. monitoring._all_events
  1932. [clinic start generated code]*/
  1933. static PyObject *
  1934. monitoring__all_events_impl(PyObject *module)
  1935. /*[clinic end generated code: output=6b7581e2dbb690f6 input=62ee9672c17b7f0e]*/
  1936. {
  1937. PyInterpreterState *interp = _PyInterpreterState_Get();
  1938. PyObject *res = PyDict_New();
  1939. if (res == NULL) {
  1940. return NULL;
  1941. }
  1942. for (int e = 0; e < _PY_MONITORING_UNGROUPED_EVENTS; e++) {
  1943. uint8_t tools = interp->monitors.tools[e];
  1944. if (tools == 0) {
  1945. continue;
  1946. }
  1947. PyObject *tools_obj = PyLong_FromLong(tools);
  1948. assert(tools_obj != NULL);
  1949. int err = PyDict_SetItemString(res, event_names[e], tools_obj);
  1950. Py_DECREF(tools_obj);
  1951. if (err < 0) {
  1952. Py_DECREF(res);
  1953. return NULL;
  1954. }
  1955. }
  1956. return res;
  1957. }
  1958. static PyMethodDef methods[] = {
  1959. MONITORING_USE_TOOL_ID_METHODDEF
  1960. MONITORING_FREE_TOOL_ID_METHODDEF
  1961. MONITORING_GET_TOOL_METHODDEF
  1962. MONITORING_REGISTER_CALLBACK_METHODDEF
  1963. MONITORING_GET_EVENTS_METHODDEF
  1964. MONITORING_SET_EVENTS_METHODDEF
  1965. MONITORING_GET_LOCAL_EVENTS_METHODDEF
  1966. MONITORING_SET_LOCAL_EVENTS_METHODDEF
  1967. MONITORING_RESTART_EVENTS_METHODDEF
  1968. MONITORING__ALL_EVENTS_METHODDEF
  1969. {NULL, NULL} // sentinel
  1970. };
  1971. static struct PyModuleDef monitoring_module = {
  1972. PyModuleDef_HEAD_INIT,
  1973. .m_name = "sys.monitoring",
  1974. .m_size = -1, /* multiple "initialization" just copies the module dict. */
  1975. .m_methods = methods,
  1976. };
  1977. PyObject *_Py_CreateMonitoringObject(void)
  1978. {
  1979. PyObject *mod = _PyModule_CreateInitialized(&monitoring_module, PYTHON_API_VERSION);
  1980. if (mod == NULL) {
  1981. return NULL;
  1982. }
  1983. if (PyObject_SetAttrString(mod, "DISABLE", &_PyInstrumentation_DISABLE)) {
  1984. goto error;
  1985. }
  1986. if (PyObject_SetAttrString(mod, "MISSING", &_PyInstrumentation_MISSING)) {
  1987. goto error;
  1988. }
  1989. PyObject *events = _PyNamespace_New(NULL);
  1990. if (events == NULL) {
  1991. goto error;
  1992. }
  1993. int err = PyObject_SetAttrString(mod, "events", events);
  1994. Py_DECREF(events);
  1995. if (err) {
  1996. goto error;
  1997. }
  1998. for (int i = 0; i < _PY_MONITORING_EVENTS; i++) {
  1999. if (add_power2_constant(events, event_names[i], i)) {
  2000. goto error;
  2001. }
  2002. }
  2003. err = PyObject_SetAttrString(events, "NO_EVENTS", _PyLong_GetZero());
  2004. if (err) goto error;
  2005. PyObject *val = PyLong_FromLong(PY_MONITORING_DEBUGGER_ID);
  2006. err = PyObject_SetAttrString(mod, "DEBUGGER_ID", val);
  2007. Py_DECREF(val);
  2008. if (err) goto error;
  2009. val = PyLong_FromLong(PY_MONITORING_COVERAGE_ID);
  2010. err = PyObject_SetAttrString(mod, "COVERAGE_ID", val);
  2011. Py_DECREF(val);
  2012. if (err) goto error;
  2013. val = PyLong_FromLong(PY_MONITORING_PROFILER_ID);
  2014. err = PyObject_SetAttrString(mod, "PROFILER_ID", val);
  2015. Py_DECREF(val);
  2016. if (err) goto error;
  2017. val = PyLong_FromLong(PY_MONITORING_OPTIMIZER_ID);
  2018. err = PyObject_SetAttrString(mod, "OPTIMIZER_ID", val);
  2019. Py_DECREF(val);
  2020. if (err) goto error;
  2021. return mod;
  2022. error:
  2023. Py_DECREF(mod);
  2024. return NULL;
  2025. }