1#include <stdio.h>
2#include <stdlib.h>
3#include <unistd.h>
4#include <string>
5
6void usage(const char* me) {
7  static const char* usage_s = "Usage:\n"
8    "  %s /system/bin/app_process <args>\n"
9    "or, better:\n"
10    "  setprop wrap.<nicename> %s\n";
11  fprintf(stderr, usage_s, me, me);
12  exit(1);
13}
14
15void env_prepend(const char* name, const char* value, const char* delim) {
16  const char* value_old = getenv(name);
17  std::string value_new = value;
18  if (value_old) {
19    value_new += delim;
20    value_new += value_old;
21  }
22  setenv(name, value_new.c_str(), 1);
23}
24
25int main(int argc, char** argv) {
26  if (argc < 2) {
27    usage(argv[0]);
28  }
29  char** args = new char*[argc];
30  // If we are wrapping app_process, replace it with app_process_asan.
31  // TODO(eugenis): rewrite to <dirname>/asan/<basename>, if exists?
32  if (strcmp(argv[1], "/system/bin/app_process") == 0) {
33    args[0] = (char*)"/system/bin/asan/app_process";
34  } else {
35    args[0] = argv[1];
36  }
37
38  for (int i = 1; i < argc - 1; ++i)
39    args[i] = argv[i + 1];
40  args[argc - 1] = 0;
41
42  env_prepend("ASAN_OPTIONS", "debug=1,verbosity=1", ",");
43  env_prepend("LD_LIBRARY_PATH", "/system/lib/asan", ":");
44  env_prepend("LD_PRELOAD", "/system/lib/libasan_preload.so", ":");
45
46  printf("ASAN_OPTIONS: %s\n", getenv("ASAN_OPTIONS"));
47  printf("LD_LIBRARY_PATH: %s\n", getenv("LD_LIBRARY_PATH"));
48  printf("LD_PRELOAD: %s\n", getenv("LD_PRELOAD"));
49
50  execv(args[0], args);
51}
52