README.md 4.01 KB
Newer Older
1 2 3 4 5
# SHVM native agent library

The purpose of this agent is to handle the invocation of REDispatch methods in
java code and send the analysis requests to the server.

6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
## Usage

The agent accepts several options, that can alter his behaviour:

### DiSL module options

Those options are used to setup the behaviour of remote instrumentation client.
Note that all of this settings takes an effect, only when `disl.allow` option
is turned on.

* `disl.allow=(true|false)` - allow the agent to act as the remote instrumentation agent,
        when this option is passed, the option `disl.instrumentation` is also
        required. Default value is false.
        
* `disl.instrumentation=jar1:jar2` - specify the `:` separated list of jar files containing
        instrumentation, that will be sent to the instrumentation server.
        
* `disl.debug` - When turned on, the behaviour of the DiSL part of the agent
        will be printed to the standard output. Default value is false.
        
* `disl.bypass=(disabled|bootstrap|dynamic)`

* `disl.server.host=localhost`

* `disl.server.port=11217`

* `disl.splitmethods`

* `disl.excepthandler`

* `disl.forcesuperclass`

* `disl.forceinterfaces`

### SHVM module options

Those options are used to setup the behaviour of remote analysis agent.

* `svm-agent.shadow.host`

* `svm-agent.shadow.port`

* `svm-agent.debug`

50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
## How is this done?

Firstly, the agent initializes itself. That means parsing the options,
requesting and veryfying the JVMTI capabilities, setting necessary callbacks
estabilishing the connection with the server, initializing of blocking queues,
registering the shared locks within JVM and launch of the sending thread.

Registered callbacks are:

* Class file load event
* Class prepare hook
* Object free hook
* JVM start hook
* JVM init hook
* JVM death hooks
* Thread end hook

Registered locks are:

* Tagging lock
* to buff lock - a.k.a. total ordering
* object free lock

Initialized blocking queues are:

* Utility queue - Holds the buffers that will be used for notifying about new
	classes, registering analysis methods etc.
* Empty queue - Holds the empty buffers
* objtag queue - This queue is consumed by object tagging queue
* send queue - consumed by sending thread.

### Class prepare callback

While the JVM loads the classes, we listen for the class prepare callback and
when the `ch.usi.dag.dislre.REDispatch` class is loaded, then we register the
REDispatch methods such as `registerMethod`, `analysisStart` etc. Those are
just the static method that can later be called from 

### Class load callback & Tagging

> Disclaimer:
> The terms "Tag" and "net reference" are used interchangeable in this memo.

The class is loaded into JVM, we are gonna send the class including its code
to the analysis server, but first is required to assign the unique identifier
to it. This is called **tagging**.

The tag is 64 bit long and has following structure:

```
| 1 : 1b | 2 : 1b | 3 : 23b | 4 : 40b |
```

1. SPEC bit - This bit indicates, whether some additional data were sent to the
	server
2. ClassInstance bit - This bit indicates, whether the object is class
	instance, or just a class. According to implementation, 1 stands for class
	here and 0 for object instance.
3. ClassID - Unique identifier of the class
4. ObjectID - Unique identifier of the object

The tags are managed by JVM, but they has to be created manually when the
class is first seen, which moment is right in that callback. While tagging,
the following two cases are distinguished:

1. Tagging a class
2. Tagging a class instance (object)

While tagging a class we need to obtain the net reference of the class loader
and also the net reference of the superclass, thus tagging can be initiated
recursively, although that shouldn't be a problem, since we probably had seen
the classloader and even the superclass loading before and they will have their
tags already. However, sending class to the observing VM is performed in this
phase.

When tagging a object, we simply obtain the tag of class and create the tag
using this and a global counter.