Create a basic agent loading framework.
Currently we only allow agents to be loaded at runtime startup, though
this is expected to change soon.
Test: ./test/run-test --host 900
Change-Id: Id648eaed4bbbe6fdef41d64922d023a4db0bfa54
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index 68fa0d3..d84cdee 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -130,6 +130,7 @@
#include "signal_set.h"
#include "thread.h"
#include "thread_list.h"
+#include "ti/agent.h"
#include "trace.h"
#include "transaction.h"
#include "utils.h"
@@ -281,6 +282,11 @@
jit_->StopProfileSaver();
}
+ // TODO Maybe do some locking.
+ for (auto& agent : agents_) {
+ agent.Unload();
+ }
+
// Make sure our internal threads are dead before we start tearing down things they're using.
Dbg::StopJdwp();
delete signal_catcher_;
@@ -960,6 +966,13 @@
experimental_flags_ = runtime_options.GetOrDefault(Opt::Experimental);
is_low_memory_mode_ = runtime_options.Exists(Opt::LowMemoryMode);
+ if (experimental_flags_ & ExperimentalFlags::kAgents) {
+ agents_ = runtime_options.ReleaseOrDefault(Opt::AgentPath);
+ // TODO Add back in -agentlib
+ // for (auto lib : runtime_options.ReleaseOrDefault(Opt::AgentLib)) {
+ // agents_.push_back(lib);
+ // }
+ }
XGcOption xgc_option = runtime_options.GetOrDefault(Opt::GcOption);
heap_ = new gc::Heap(runtime_options.GetOrDefault(Opt::MemoryInitialSize),
runtime_options.GetOrDefault(Opt::HeapGrowthLimit),
@@ -1232,6 +1245,20 @@
is_native_bridge_loaded_ = LoadNativeBridge(native_bridge_file_name);
}
+ // Startup agents
+ // TODO Maybe we should start a new thread to run these on. Investigate RI behavior more.
+ for (auto& agent : agents_) {
+ // TODO Check err
+ int res = 0;
+ std::string err = "";
+ ti::Agent::LoadError result = agent.Load(&res, &err);
+ if (result == ti::Agent::kInitializationError) {
+ LOG(FATAL) << "Unable to initialize agent!";
+ } else if (result != ti::Agent::kNoError) {
+ LOG(ERROR) << "Unable to load an agent: " << err;
+ }
+ }
+
VLOG(startup) << "Runtime::Init exiting";
return true;