| 1 | = Running dynamic call analysis = |
| 2 | |
| 3 | Dynamic function calls are either dynamic MFA calls (those MFA calls whose callee is given by means of non-literal expressions) or apply calls (calls to the ''erlang:apply/3'' built-in function). |
| 4 | |
| 5 | For instance, the following calls inside ''f'' are dynamic: |
| 6 | {{{ |
| 7 | f(IOModule) -> |
| 8 | Foo = ["foo"], |
| 9 | IOModule:format("foo"), |
| 10 | apply(IOModule, format, Foo). |
| 11 | }}} |
| 12 | |
| 13 | These constructs are likely difficult to be statically analysed, since their callee is determined only at execution-time. Fortunately, in many cases static code analysis is able to find potential callees, but unlike other semantic analyses in !RefactorErl, dynamic call analysis would be very inefficient to be performed incrementally. Therefore, static analysis of dynamic function calls has to be triggered by the user on demand. |
| 14 | |
| 15 | In order to analyse dynamic call constructs, load all the libraries and files you would like to work with. Then type in the !RefactorErl shell: |
| 16 | |
| 17 | {{{ |
| 18 | ri:anal_dyn(). |
| 19 | }}} |
| 20 | |
| 21 | Dynamic call analysis begins and informs you about the process and its progress. Firstly, all function calls are gathered from the database. Secondly, dynamic ones are filtered and passed to the next step, where a parallel algorithm tries to identify the callee |
| 22 | of each call. Finally, the results are merged and stored into the database. |
| 23 | |
| 24 | For instance, executed on ''Erlang stdlib 1.17.4'': |
| 25 | |
| 26 | {{{ |
| 27 | 24012 function calls found in the database. |
| 28 | Looking for dynamic calls... |
| 29 | 541 function calls seem to be dynamic. |
| 30 | Looking up dynamic calls... (533/541) |
| 31 | Identification of 8 dynamic calls timed out. |
| 32 | |
| 33 | 533 dynamic calls identified in the database. |
| 34 | Analysing dynamic calls... (533/533) |
| 35 | |
| 36 | Analysis completed. |
| 37 | }}} |
| 38 | |
| 39 | As you can see in this example, there may be function calls that are not identifiable in a reasonable time (currently the time limit is set to 5 seconds, and there were 8 calls whose analysis has been ignored). This is due to the complexity of some data-flow path |
| 40 | analysis. Users may increase the time bound on their own risk in order to make the analysis process able to identify all the callees. |
| 41 | |
| 42 | '''Please note that most database modifications (e.g. loading or refactoring a module) may invalidate the results of this dynamic call analysis. Currently this invalidation step is not automatically done, so the user has to invoke it. To clean the dynamic calls (and every corresponding entry) from the database, simply call:''' |
| 43 | |
| 44 | {{{ |
| 45 | ri:clean_dyn(). |
| 46 | }}} |