--- /dev/null
+%SWAP Python tool user guide
+
+**SWAP Python tool** is a python library which implements **SWAP** tool
+host-side. It is used for interacting with SWAP daemon, located on target. If
+your device contains an installed version of **SWAP**, you can interact with it
+using **SWAP Python tool**. For more detailed information about **SWAP** itself,
+please read *SWAP documentation*.
+
+**SWAP Python tool** can be used as a part of another application or, using
+its example as a reference, as a standalone tool.
+
+## Getting tool
+**SWAP Python tool** is provided as a part of ***swap-manager***. To get
+**SWAP Python tool** please do the following steps:
+
+- clone **swap-manager** sources and checkout to *tizen* branch:
+``` bash
+ $ git clone git://git.tizen.org/platform/core/system/swap-manager
+ $ cd swap-manager && git checkout tizen
+```
+
+## Run
+
+### Config files description
+**SWAP Pyton tool** sources contain an example of tool configuration files,
+located at *\<swap-manager\>/src/cli/example/*. The folder contains several
+config files:
+
++-----------------+--------------------------------------------------------------------------+----------------------------------------------------------------------------+
+| File | Content | Description |
++:================+:=========================================================================+:===========================================================================+
+| |``` python | Provides target device/emulator configuration. |
+| emulator.py | api_version = '1.0' | |
+| | | ```api_version``` - used to verify compatibility of different config files |
+| | connection = { | |
+| | 'ip': "127.0.0.1", | ```connection``` - dictionary, containing data about the connection with |
+| | 'port': 8001, | the target |
+| | | |
+| | 'type': "sdb", | * ```ip``` - target IP address |
+| | 'type_info': { | * ```port``` - target port |
+| | 'target': 'emulator', | |
+| | }, | * ```type``` - target connection type. Possible values: |
+| | } | |
+| |``` | * ```ssh``` - for SSH connection |
+| | | * ```sdb``` - for SDB connection |
+| | | * ```alone``` - for standalone profiling |
+| | | * ```type_info``` - information about selected connection type, differs for|
+| | | different type: |
+| | | |
+| | | * for ```sdb```: |
+| | | |
+| | | * ```target``` - target type, ```emulator```, ```device``` and |
+| | | ```serial``` are supported; |
+| | | * for ```ssh```: |
+| | | |
+| | | * ```params``` - SSH connection parameters; |
+| | | * ```username``` - SSH username. |
++-----------------+--------------------------------------------------------------------------+----------------------------------------------------------------------------+
+| |``` python | Provides application's profiling session configuration. |
+| example_conf.py | api_version = '1.0' | |
+| | | ```api_version``` - used to verify compatibility of different config files |
+| | sampling = { | |
+| | "period": 50, | ```sampling``` - turns on SWAP sampling feature and contains its options: |
+| | } | |
+| | | * ```period``` - a period of sampling |
+| | features = [ | |
+| | 'memory', | ```features``` - features, that doesn't require additional options, are |
+| | 'file', | turned on by including to this list. Available features are: |
+| | 'network', | |
+| | 'thread', | * ```memory``` - memory API profiling feature for target binaries; |
+| | 'opengl', | * ```file``` - file API profiling feature for target binaries; |
+| | 'memory_for_all', | * ```network``` - network API profiling feature for target binaries; |
+| | 'file_for_all', | * ```thread``` - thread API profiling feature for target binaries; |
+| | 'network_for_all', | * ```opengl``` - OpenGL API profiling feature; |
+| | 'thread_for_all', | * ```memory_for_all``` - memory API profiling for all process binaries; |
+| | 'context_switch', | * ```file_for_all``` - file API profiling for all process binaries; |
+| | 'lsan' | * ```network_for_all``` - network API profiling for all process binaries; |
+| | ] | * ```context_switch``` - context switch profiling; |
+| | | * ```lsan``` - Leak Sanitizer feature; |
+| | app = { | |
+| | 'app_info': { | ```app``` - dictionary that contains application profiling data and |
+| | 'type': 'NATIVE', 'id': 'org.example.filemanager', | options: |
+| | }, | |
+| | | * ```app_info``` - dictionary that specifies application for profiling: |
+| | 'function_inst': { | |
+| | '/opt/usr/globalapps/org.example.filemanager/bin/filemanager': [ | * ```type``` - application type, possible values are: |
+| | ('main', 'xxxx', 'd'), | |
+| | ], | * ```NATIVE``` - for Tizen native applications; |
+| | '/lib/libc.so.6': [ | * ```COMMON``` - for console applications (isn't supported by **SWAP**,|
+| | ('malloc', 'd', 'p'), | check *SWAP documentation* for details); |
+| | ], | * ```RUNNING``` - for already running applications (isn't supported by |
+| | }, | **SWAP**, check *SWAP documentation* for details); |
+| | } | * ```WEB``` - for Tizen web applications (doesn't supported by check |
+| |``` | *SWAP documentation* for details); |
+| | | |
+| | | * the second parameter depends on the ```type``` value: |
+| | | |
+| | | * for ```NATIVE```: |
+| | | |
+| | | * ```id``` - Tizen native application ID; |
+| | | |
+| | | * for ```COMMON```: |
+| | | |
+| | | * ```path``` - path where application binary is located; |
+| | | |
+| | | * for ```RUNNING```: |
+| | | |
+| | | * ```pid``` - PID of the target process. There is a special case for |
+| | | ```'pid': -1``` - this causes system-wide instrumentation for all |
+| | | processes; |
+| | | * ```id``` - Tizen ID of the target application; |
+| | | * ```path``` - path where application binary is located; |
+| | | |
+| | | * for ```WEB```: |
+| | | |
+| | | * ```id``` - Tizen web application ID. |
+| | | |
+| | | * ```function_inst``` - dictionary that contains information about binary |
+| | | instrumentation probes: |
+| | | |
+| | | * each key of a dictionary is a path to binary for profiling; |
+| | | * each value is an array for the key binary that contains tuples of the |
+| | | following format: |
+| | | |
+| | | * function name in ```''``` or address; |
+| | | * string that describes arguments of a target function, one character |
+| | | for each argument. The following values are accepted: |
+| | | |
+| | | * ```b``` - for bool value; |
+| | | * ```c``` - for char value; |
+| | | * ```f``` - for float value; |
+| | | * ```d``` - for int value; |
+| | | * ```x``` - for long value; |
+| | | * ```p``` - for pointer value; |
+| | | * ```w``` - for double value; |
+| | | * ```s``` - for C-string; |
+| | | |
+| | | * character that describes returned value. Accepted all characters |
+| | | for arguments and more: |
+| | | * ```v``` and ```n``` - for function returns void |
++-----------------+--------------------------------------------------------------------------+----------------------------------------------------------------------------+
+
+Such config files should be provided for **SWAP Python tool** in a way described
+below.
+
+### API and usage description
+
+**SWAP Python tool** example also contains tools API usage example in
+*example.py* file:
+
++-----------------+--------------------------------------------------------------------------+----------------------------------------------------------------------------+
+| File | Content | Description |
++:================+:=========================================================================+:===========================================================================+
+| |``` python | |
+| example.py | #!/usr/bin/python2 | To use **SWAP Python tool** ```swap``` module should be imported from |
+| | | *swap_cli* folder. |
+| | import time | |
+| | from swap_cli import swap | **SWAP Python tool** interface is provided via ```Client``` class object. |
+| | | ```Client``` class object constructor takes path to the target config as |
+| | def simple_cb(data): | an argument, so the user should have one ```Client``` for each target. |
+| | pass | To provide profiling session configuration, ```load_config()``` method is |
+| | | used, it takes profiling session config file as an argument. |
+| | # load configs | |
+| | c = swap.Client('example/emulator.py') | After necessary configurations are loaded, some additional preparations |
+| | c.load_config(['example/example_conf.py']) | can be done, for example, in this example callback is set on |
+| | c.set_event_cb('MSG_PROCESS_INFO', simple_cb) | ```MSG_PROCESS_INFO``` - it will be called when ```MSG_PROCESS_INFO``` |
+| | | will be received. |
+| | # instrumentation | |
+| | c.start('/tmp/outdir') | Profiling is started by ```start()``` method, it takes output folder path |
+| | time.sleep(60) | as an argument. In an output folder, you can find trace and another |
+| | c.stop() | additional data (LSan reports) after profiling. |
+| |``` | |
+| | | Profiling is finished by calling ```stop()``` method. |
++-----------------+--------------------------------------------------------------------------+----------------------------------------------------------------------------+
+
+The whole **SWAP Python tool** API is described below:
+
++-------------------------------------+-------------------------------------+----------------+----------------------------------------------------------------------------+
+| API name | Parameters | Return value | Description |
++:====================================+:====================================+:===============+:===========================================================================+
+| ```class Client``` | ```target_conf``` - string path to | object of | ```Client``` class provides all **SWAP Python tool** functionality, which |
+| | a file, that contains target | ```Client``` | is implemented as methods of the class. |
+| (constructor) ```(target_conf)``` | device/emulator config (see | class | The class constructor takes target configuration file path as an argument, |
+| | above description of | | so, if several different targets are used for profiling, several |
+| | *emulator.py* for details) | | ```Client``` class objects should be created. |
+| | | | |
+| | | | Configuration file description and details can be found above as a |
+| | | | description of *emulator.py*. |
++-------------------------------------+-------------------------------------+----------------+----------------------------------------------------------------------------+
+| ```get_version()``` | None | string that | Returns **SWAP Python tool** version. |
+| | | matches | |
+| | | **SWAP Python | |
+| | | tool** version | |
++-------------------------------------+-------------------------------------+----------------+----------------------------------------------------------------------------+
+| ```load_config(path)``` | ```path``` - string, path to a file | None | This function is used to load application's profiling data, i.e. what |
+| | that contains profiling session | | application is a target one, which features should be used. |
+| | configuration (see above description| | |
+| | of *example_conf.py* for details) | | *example_conf.py* can be used as an example of this configuration file, |
+| | | | its description above covers all of the possible meanings. |
++-------------------------------------+-------------------------------------+----------------+----------------------------------------------------------------------------+
+| ```set_event_cb(event, callback)``` | ```event``` - string, that matches | None | This function allows registering user-defined callback on any received |
+| | message name; | | SWAP message. |
+| | | | |
+| | ```callback``` - pointer to a | | Event name depends on a protocol that is being used and can be received |
+| | function that will be called when | | from protocol description. For example, protocol 4.2 supports the |
+| | ```event``` message is received | | following event names: |
+| | | | |
+| | | | * ```MSG_PROCESS_INFO``` |
+| | | | * ```MSG_TERMINATE``` |
+| | | | * ```MSG_ERROR``` |
+| | | | * ```MSG_SAMPLE``` |
+| | | | * ```MSG_SYSTEM``` |
+| | | | * ```MSG_FUNCTION_ENTRY``` |
+| | | | * ```MSG_FUNCTION_EXIT``` |
+| | | | * ```MSG_SYSCALL_ENTRY``` |
+| | | | * ```MSG_SYSCALL_EXIT``` |
+| | | | * ```MSG_FILE_FUNCTION_ENTRY``` |
+| | | | * ```MSG_FILE_FUNCTION_EXIT``` |
+| | | | * ```MSG_PROCESS_STATUS_INFO``` |
+| | | | * ```MSG_CONTEXT_SWITCH_ENTRY``` |
+| | | | * ```MSG_CONTEXT_SWITCH_EXIT``` |
+| | | | * ```MSG_PROCESS_MAP``` |
+| | | | * ```MSG_PROCESS_UNMAP``` |
+| | | | * ```MSG_WEB_SAMPLING``` |
+| | | | * ```MSG_APP_SETUP_STAGE``` |
+| | | | * ```MSG_WEB_APP_SETUP_STAGE``` |
+| | | | * ```MSG_FBI``` |
+| | | | * ```MSG_UI_HIERARCHY``` |
+| | | | * ```MSG_PROBE_MEMORY``` |
+| | | | * ```MSG_PROBE_UIEVENT``` |
+| | | | * ```MSG_PROBE_RESOURCE``` |
+| | | | * ```MSG_PROBE_LIFECYCLE``` |
+| | | | * ```MSG_PROBE_SCREENSHOT``` |
+| | | | * ```MSG_PROBE_THREAD``` |
+| | | | * ```MSG_PROBE_SYNC``` |
+| | | | * ```MSG_PROBE_NETWORK``` |
+| | | | * ```MSG_PROBE_GL``` |
+| | | | * ```MSG_LSAN``` |
+| | | | |
+| | | | To get description which message stands for which event, please refer to |
+| | | | the protocol description. |
+| | | | |
+| | | | ```callback``` is a pointer to the callback function which should be called|
+| | | | when ```event``` message is received. The callback function should have |
+| | | | the following prototype: |
+| | | | |
+| | | | ```callback(data)``` |
+| | | | |
+| | | | where ```data``` is message payload. Payload has a protocol- and |
+| | | | message-specific format, so, please refer to the protocol description for |
+| | | | details. |
++-------------------------------------+-------------------------------------+----------------+----------------------------------------------------------------------------+
+| ```start(outdir)``` | ```outdir``` - string with path to | None | ```start()``` establishes connection between **SWAP Python tool** on host |
+| | an output directory where trace, | | and **SWAP** on target and starts profiling target application. After |
+| | LSan reports, necessary target | | workflow has returned from ```start()``` **SWAP** is supposed to be |
+| | info etc. will be located. | | executed on target. |
+| | The directory will be created if it | | |
+| | doesn't exist. | | Trace is saved to *\<outdir\>/trace.bin* file. |
++-------------------------------------+-------------------------------------+----------------+----------------------------------------------------------------------------+
+| ```is_alive()``` | None | bool - True if | Function checks if connection with target **SWAP** works and if **SWAP** |
+| | | **SWAP** | responds on host's requests. |
+| | | has returned | |
+| | | response, False| |
+| | | otherwise | |
++-------------------------------------+-------------------------------------+----------------+----------------------------------------------------------------------------+
+| ```stop()``` | None | | Stops tracing, closes connection with the target **SWAP**. |
++-------------------------------------+-------------------------------------+----------------+----------------------------------------------------------------------------+
+
+### Example execution
+
+To run **SWAP Python tool** example, the user should do the following steps:
+
+1. Install target application with debug flag. Applications installed without
+debug flag are restricted for profiling due to security reasons;
+2. Edit *emulator.py* according to the user's target:
+ 1) set proper connection type for the filed ```type``` in ```connection```
+ dictionary;
+ 2) if the type is ssh, set ```ip``` and ```port``` values;
+ 3) add information about connection type:
+ - if connection is established via ```sdb```, set ```emulator```,
+ ```device``` or ```serial``` value for ```target``` field of
+ ```type_info``` dictionary;
+ - if connection is established via ```ssh```, set SSH connection
+ parameters for ```params``` field and SSH username for ```username```
+ field of ```type_info``` dictionary;
+3. Edit *example_conf.py* according to the target application data:
+ 1) set target application type to field ```type``` of ```app_info```
+ dictionary that is contained in ```app``` dictionary. Now only ```NATIVE```
+ applications are supported due to security reasons;
+ 2) set Tizen application ID to field ```id``` of ```app_info``` dictionary;
+ 3) add data about features desirable to use:
+ - if the user wants to use Sampling feature, add ```sampling```
+ dictionary somewhere in file and add ```period``` field in it with the
+ desirable period of sampling;
+ - if the user wants to use any of Memory profiling, File profiling,
+ Network profiling, Thread profiling, OpenGL profiling, Context switch
+ profiling, Leak Sanitizer features, add ```features``` list somewhere
+ in the file and add here ```'memory'```, ```'file'```, ```'network'```,
+ ```'thread'```, ```'opengl'```, ```'context_switch'```, ```'lsan'```
+ values accordingly. For always profiling version of the features, add
+ ```for_all``` for these features;
+ 4) add necessary user probes for the binaries of interest. To add probe
+ on the binary do the following:
+ - add a key-value pair to ```function_inst``` dictionary that is
+ contained in ```app``` dictionary. The key should be a string with
+ a full path to the binary, the value should be a list;
+ - add tuple to the list;
+ - add name or address of the function of interest to the tuple as the
+ first value. Name should be a string, address should be an integer;
+ - add string that represents function arguments to the tuple as the
+ second value. For the information about possible values, please refer
+ to the [Config files description](#config-files-description) section;
+ - add string with a character that represents return value of the
+ function to the tuple as the third value. For the information about
+ possible values, please refer to the
+ [Config files description](#config-files-description) section;
+4. Change directory to the *cli* directory and execute *example.py*:
+``` python
+ $ cd <swap-manager>/src/cli/
+ $ python -m example.example
+```
+5. All artifacts of the profiling session will be placed at the specified
+```outdir``` on stop. For parsing the trace, please refer to the Trace Parser
+documentation.