Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(440)

Side by Side Diff: tools/android/memtrack_helper/memtrack_helper.c

Issue 2576713002: Fix memtrack_helper for newer versions Android. (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright 2015 The Chromium Authors. All rights reserved. 2 * Copyright 2015 The Chromium Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be 3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file. 4 * found in the LICENSE file.
5 */ 5 */
6 6
7 #include "tools/android/memtrack_helper/memtrack_helper.h" 7 #include "tools/android/memtrack_helper/memtrack_helper.h"
8 8
9 #include <dlfcn.h> 9 #include <dlfcn.h>
10 #include <errno.h> 10 #include <errno.h>
11 #include <fcntl.h>
12 #include <signal.h>
13 #include <stdio.h> 11 #include <stdio.h>
14 #include <stdlib.h> 12 #include <stdlib.h>
15 #include <string.h> 13 #include <string.h>
16 #include <unistd.h>
17 #include <sys/socket.h> 14 #include <sys/socket.h>
18 #include <sys/un.h> 15 #include <sys/un.h>
19 #include <sys/stat.h> 16 #include <sys/stat.h>
20 #include <sys/types.h> 17 #include <sys/types.h>
21 #include <sys/wait.h>
22 18
23 /* 19 /*
24 * This is a helper daemon for Android which makes memtrack graphics information 20 * This is a helper daemon for Android which makes memtrack graphics information
25 * accessible via a UNIX socket. It is used by telemetry and memory-infra. 21 * accessible via a UNIX socket. It is used by telemetry and memory-infra.
26 * More description in the design-doc: https://goo.gl/4Y30p9 . 22 * More description in the design-doc: https://goo.gl/4Y30p9 .
27 */ 23 */
28 24
29 static const char kShutdownRequest = 'Q'; 25 static const char kShutdownRequest = 'Q';
30 26
31 // See $ANDROID/system/core/include/memtrack/memtrack.h. 27 // See $ANDROID/system/core/include/memtrack/memtrack.h.
32 typedef void* memtrack_proc_handle; 28 struct memtrack_proc;
Primiano Tucci (use gerrit) 2016/12/14 15:51:16 why this? we don't care what's the real type of th
kraynov 2016/12/15 15:43:47 Done.
29 typedef struct memtrack_proc* memtrack_proc_handle;
33 typedef int (*memtrack_init_t)(void); 30 typedef int (*memtrack_init_t)(void);
34 typedef memtrack_proc_handle (*memtrack_proc_new_t)(void); 31 typedef memtrack_proc_handle (*memtrack_proc_new_t)(void);
35 typedef void (*memtrack_proc_destroy_t)(memtrack_proc_handle); 32 typedef void (*memtrack_proc_destroy_t)(memtrack_proc_handle);
36 typedef int (*memtrack_proc_get_t)(memtrack_proc_handle, pid_t); 33 typedef int (*memtrack_proc_get_t)(memtrack_proc_handle, pid_t);
37 typedef ssize_t (*memtrack_proc_graphics_total_t)(memtrack_proc_handle); 34 typedef ssize_t (*memtrack_proc_graphics_total_t)(memtrack_proc_handle);
38 typedef ssize_t (*memtrack_proc_graphics_pss_t)(memtrack_proc_handle); 35 typedef ssize_t (*memtrack_proc_graphics_pss_t)(memtrack_proc_handle);
39 typedef ssize_t (*memtrack_proc_gl_total_t)(memtrack_proc_handle); 36 typedef ssize_t (*memtrack_proc_gl_total_t)(memtrack_proc_handle);
40 typedef ssize_t (*memtrack_proc_gl_pss_t)(memtrack_proc_handle); 37 typedef ssize_t (*memtrack_proc_gl_pss_t)(memtrack_proc_handle);
41 typedef ssize_t (*memtrack_proc_other_total_t)(memtrack_proc_handle); 38 typedef ssize_t (*memtrack_proc_other_total_t)(memtrack_proc_handle);
42 typedef ssize_t (*memtrack_proc_other_pss_t)(memtrack_proc_handle); 39 typedef ssize_t (*memtrack_proc_other_pss_t)(memtrack_proc_handle);
(...skipping 16 matching lines...) Expand all
59 static void send_shutdown_request(struct sockaddr_un* addr) { 56 static void send_shutdown_request(struct sockaddr_un* addr) {
60 int sock = socket(AF_UNIX, SOCK_SEQPACKET, 0); 57 int sock = socket(AF_UNIX, SOCK_SEQPACKET, 0);
61 connect(sock, (struct sockaddr*)addr, sizeof(*addr)); 58 connect(sock, (struct sockaddr*)addr, sizeof(*addr));
62 send(sock, &kShutdownRequest, 1, 0); 59 send(sock, &kShutdownRequest, 1, 0);
63 close(sock); 60 close(sock);
64 } 61 }
65 62
66 static void handle_one_request(int client_sock) { 63 static void handle_one_request(int client_sock) {
67 char buf[32]; 64 char buf[32];
68 char response[4096] = ""; 65 char response[4096] = "";
69 ssize_t rsize = recv(client_sock, buf, sizeof(buf), 0); 66 ssize_t rsize = recv(client_sock, buf, sizeof(buf) - 1, 0);
67 buf[rsize] = '\0';
Primiano Tucci (use gerrit) 2016/12/14 15:51:16 now this will crash if recv fails and rsize = -1 I
kraynov 2016/12/15 15:43:48 Done.
70 68
71 if (rsize < 1) 69 if (rsize < 1)
72 return; 70 return;
73 71
74 if (buf[0] == kShutdownRequest) 72 if (buf[0] == kShutdownRequest)
75 exit(EXIT_SUCCESS); 73 exit(EXIT_SUCCESS);
76 74
77 pid_t pid = -1; 75 pid_t pid = -1;
78 if (sscanf(buf, "%d", &pid) != 1) 76 if (sscanf(buf, "%d", &pid) != 1 || pid < 0)
79 return send_response(client_sock, "ERR invalid pid"); 77 return send_response(client_sock, "ERR invalid pid");
80 78
81 memtrack_proc_handle handle = memtrack_proc_new(); 79 memtrack_proc_handle handle = memtrack_proc_new();
82 if (!handle) 80 if (!handle)
83 return send_response(client_sock, "ERR memtrack_proc_new()"); 81 return send_response(client_sock, "ERR memtrack_proc_new()");
84 82
85 if (memtrack_proc_get(handle, pid)) { 83 if (memtrack_proc_get(handle, pid)) {
86 memtrack_proc_destroy(handle); 84 memtrack_proc_destroy(handle);
87 return send_response(client_sock, "ERR memtrack_proc_get()"); 85 return send_response(client_sock, "ERR memtrack_proc_get()");
88 } 86 }
89 87
90 char* response_ptr = &response[0]; 88 char* response_ptr = &response[0];
91 if (memtrack_proc_graphics_total) { 89 if (memtrack_proc_graphics_total) {
92 response_ptr += sprintf(response_ptr, "graphics_total %zd\n", 90 response_ptr += sprintf(response_ptr, "graphics_total %zd\n",
93 memtrack_proc_graphics_total(handle)); 91 memtrack_proc_graphics_total(handle));
94 } 92 }
95 if (memtrack_proc_graphics_pss) { 93 if (memtrack_proc_graphics_pss) {
96 response_ptr += sprintf(response_ptr, "graphics_pss %zd\n", 94 response_ptr += sprintf(response_ptr, "graphics_pss %zd\n",
97 memtrack_proc_graphics_pss(handle)); 95 memtrack_proc_graphics_pss(handle));
98 } 96 }
99 if (memtrack_proc_gl_total) { 97 if (memtrack_proc_gl_total) {
100 response_ptr += 98 response_ptr += sprintf(response_ptr, "gl_total %zd\n",
101 sprintf(response_ptr, "gl_total %zd\n", memtrack_proc_gl_total(handle)); 99 memtrack_proc_gl_total(handle));
102 } 100 }
103 if (memtrack_proc_gl_pss) { 101 if (memtrack_proc_gl_pss) {
104 response_ptr += 102 response_ptr += sprintf(response_ptr, "gl_pss %zd\n",
105 sprintf(response_ptr, "gl_pss %zd\n", memtrack_proc_gl_pss(handle)); 103 memtrack_proc_gl_pss(handle));
106 } 104 }
107 if (memtrack_proc_other_total) { 105 if (memtrack_proc_other_total) {
108 response_ptr += sprintf(response_ptr, "other_total %zd\n", 106 response_ptr += sprintf(response_ptr, "other_total %zd\n",
109 memtrack_proc_other_total(handle)); 107 memtrack_proc_other_total(handle));
110 } 108 }
111 if (memtrack_proc_other_pss) { 109 if (memtrack_proc_other_pss) {
112 response_ptr += sprintf(response_ptr, "other_pss %zd\n", 110 response_ptr += sprintf(response_ptr, "other_pss %zd\n",
113 memtrack_proc_other_pss(handle)); 111 memtrack_proc_other_pss(handle));
114 } 112 }
115 113
116 memtrack_proc_destroy(handle); 114 memtrack_proc_destroy(handle);
117 send_response(client_sock, response); 115 send_response(client_sock, response);
118 } 116 }
119 117
120 static void daemonize() {
121 pid_t pid;
122
123 pid = fork();
124 if (pid < 0)
125 exit_with_failure("fork");
126 if (pid > 0) {
127 /* Terminate the main process attached to TTY once the daemon re-forks. */
128 int ignore;
129 wait(&ignore);
130 exit(EXIT_SUCCESS);
131 }
132
133 if (setsid() == -1)
134 exit_with_failure("setsid");
135
136 chdir("/");
137 umask(0);
138 close(STDIN_FILENO);
139 close(STDOUT_FILENO);
140 close(STDERR_FILENO);
141 open("/dev/null", O_RDONLY);
142 open("/dev/null", O_WRONLY);
143 open("/dev/null", O_RDWR);
144
145 pid = fork();
146 if (pid < 0)
147 exit_with_failure("fork");
148 if (pid > 0)
149 exit(EXIT_SUCCESS);
150 }
151
152 int main(int argc, char** argv) { 118 int main(int argc, char** argv) {
153 int res; 119 int res;
154 120
155 if (getuid() != 0) { 121 if (getuid() != 0) {
156 fprintf(stderr, "FATAL: %s must be run as root!\n", argv[0]); 122 fprintf(stderr, "FATAL: %s must be run as root!\n", argv[0]);
157 return EXIT_FAILURE; 123 return EXIT_FAILURE;
158 } 124 }
159 125
160 void* const libhandle = dlopen("libmemtrack.so", RTLD_GLOBAL | RTLD_NOW); 126 void* const libhandle = dlopen("libmemtrack.so", RTLD_GLOBAL | RTLD_NOW);
161 if (!libhandle) 127 if (!libhandle)
(...skipping 11 matching lines...) Expand all
173 libhandle, "memtrack_proc_graphics_pss"); 139 libhandle, "memtrack_proc_graphics_pss");
174 memtrack_proc_gl_total = 140 memtrack_proc_gl_total =
175 (memtrack_proc_gl_total_t)dlsym(libhandle, "memtrack_proc_gl_total"); 141 (memtrack_proc_gl_total_t)dlsym(libhandle, "memtrack_proc_gl_total");
176 memtrack_proc_gl_pss = 142 memtrack_proc_gl_pss =
177 (memtrack_proc_gl_pss_t)dlsym(libhandle, "memtrack_proc_gl_pss"); 143 (memtrack_proc_gl_pss_t)dlsym(libhandle, "memtrack_proc_gl_pss");
178 memtrack_proc_other_total = (memtrack_proc_other_total_t)dlsym( 144 memtrack_proc_other_total = (memtrack_proc_other_total_t)dlsym(
179 libhandle, "memtrack_proc_other_total"); 145 libhandle, "memtrack_proc_other_total");
180 memtrack_proc_other_pss = 146 memtrack_proc_other_pss =
181 (memtrack_proc_other_pss_t)dlsym(libhandle, "memtrack_proc_other_pss"); 147 (memtrack_proc_other_pss_t)dlsym(libhandle, "memtrack_proc_other_pss");
182 148
183 if (!memtrack_init || !memtrack_proc_new || !memtrack_proc_destroy || 149 if (!memtrack_proc_new || !memtrack_proc_destroy || !memtrack_proc_get) {
184 !memtrack_proc_get) {
185 exit_with_failure("dlsym() libmemtrack.so"); 150 exit_with_failure("dlsym() libmemtrack.so");
186 } 151 }
187 152
188 const int server_fd = socket(AF_UNIX, SOCK_SEQPACKET, 0); 153 const int server_fd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
189 if (server_fd < 0) 154 if (server_fd < 0)
190 exit_with_failure("socket"); 155 exit_with_failure("socket");
191 156
192 /* Initialize the socket */ 157 /* Initialize the socket */
193 struct sockaddr_un server_addr; 158 struct sockaddr_un server_addr;
194 init_memtrack_server_addr(&server_addr); 159 init_memtrack_server_addr(&server_addr);
195 160
196 /* Shutdown previously running instances if any. */ 161 /* Shutdown previously running instances if any. */
197 int i; 162 int i;
198 for (i = 0; i < 3; ++i) { 163 for (i = 0; i < 3; ++i) {
199 res = bind(server_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)); 164 res = bind(server_fd, (struct sockaddr*)&server_addr, sizeof(server_addr));
200 if (res && errno == EADDRINUSE) { 165 if (res && errno == EADDRINUSE) {
201 send_shutdown_request(&server_addr); 166 send_shutdown_request(&server_addr);
202 usleep(250000); 167 usleep(250000);
203 continue; 168 continue;
204 } 169 }
205 break; 170 break;
206 } 171 }
207 172
208 if (res) 173 if (res)
209 exit_with_failure("bind"); 174 exit_with_failure("bind");
210 175
211 if (argc > 1 && strcmp(argv[1], "-d") == 0) 176 if (argc > 1 && strcmp(argv[1], "-d") == 0) {
212 daemonize(); 177 int res = daemon(0, 0);
178 if (res != 0)
179 exit_with_failure("Failed to daemonize.");
180 }
181 log_pid();
213 182
214 res = memtrack_init(); 183 if (memtrack_init) {
215 if (res == -ENOENT) { 184 res = memtrack_init();
216 exit_with_failure("Unable to load memtrack module in libhardware. " 185 if (res == -ENOENT) {
217 "Probably implementation is missing in this ROM."); 186 exit_with_failure("Unable to load memtrack module in libhardware. "
218 } else if (res != 0) { 187 "Probably implementation is missing in this ROM.");
219 exit_with_failure("memtrack_init() returned non-zero status."); 188 } else if (res != 0) {
189 exit_with_failure("memtrack_init() returned non-zero status.");
190 }
191 } else {
192 // memtrack_init() has been removed in newer versions of libmemtrack and
193 // replaced with lazy initialization. This code triggers that.
194 memtrack_proc_handle handle = memtrack_proc_new();
195 if (!handle)
196 exit_with_failure("memtrack_proc_new() failed.");
197 if (memtrack_proc_get(handle, getpid()) != 0)
Primiano Tucci (use gerrit) 2016/12/14 15:51:16 Hmm I'd remove this. Since this is a non-(Java)-ma
kraynov 2016/12/15 15:43:47 Acknowledged.
198 exit_with_failure("memtrack_proc_get() returned non-zero status.");
199 memtrack_proc_destroy(handle);
220 } 200 }
221 201
222 if (listen(server_fd, 128 /* max number of queued requests */)) 202 if (listen(server_fd, 128 /* max number of queued requests */))
223 exit_with_failure("listen"); 203 exit_with_failure("listen");
224 204
225 for (;;) { 205 for (;;) {
226 struct sockaddr_un client_addr; 206 struct sockaddr_un client_addr;
227 socklen_t len = sizeof(client_addr); 207 socklen_t len = sizeof(client_addr);
228 int client_sock = accept(server_fd, (struct sockaddr*)&client_addr, &len); 208 int client_sock = accept(server_fd, (struct sockaddr*)&client_addr, &len);
229 handle_one_request(client_sock); 209 handle_one_request(client_sock);
230 close(client_sock); 210 close(client_sock);
231 } 211 }
232 212
233 return EXIT_SUCCESS; 213 return EXIT_SUCCESS;
234 } 214 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698