Stackdb
Stackdb is a stackable, multi-target and -level source debugger and memory forensics library.
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
nullpage_check.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014 The University of Utah
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of
7  * the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
17  */
18 
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <errno.h>
22 #include <string.h>
23 #include <inttypes.h>
24 #include <signal.h>
25 #include <argp.h>
26 
27 #include "log.h"
28 #include "dwdebug.h"
29 #include "target_api.h"
30 #include "target.h"
31 
32 #include "probe_api.h"
33 #include "probe.h"
34 #include "alist.h"
35 #include "list.h"
36 
37 #include "nullpage.h"
38 
39 struct target *target = NULL;
40 struct probe *np_probe = NULL;
41 struct np_config npc;
42 
44  if (np_probe) {
45  target_pause(target);
46  probe_free(np_probe,1);
47  np_probe = NULL;
48  }
49 }
50 
51 void sigh_cleanup_probes(int signo,siginfo_t *siginfo,void *x) {
53 }
54 
55 void print_thread_context(FILE *stream,struct target *target,tid_t tid,
56  int ttctx,int ttdetail,int bt,char *sep,char *kvsep,
57  char *tprefix,char *tsep) {
58  struct target_thread *tthread;
59  char buf[1024];
60  struct array_list *tids;
61  int i;
62  int rc;
63 
64  tthread = target_lookup_thread(target,tid);
65 
66  if (ttctx == 0)
67  return;
68  else if (ttctx == 1) {
69  if (target_thread_snprintf(target,tid,buf,sizeof(buf),
70  ttdetail,sep,kvsep) < 0)
71  fprintf(stream,"%s[tid=%"PRIiTID"",tprefix,tid);
72  else
73  fprintf(stream,"%s[%s",tprefix,buf);
74  if (bt) {
75  rc = target_unwind_snprintf(buf,sizeof(buf),target,tid,
77  if (rc < 0)
78  fprintf(stream,"%sbacktrace=[error!]",sep);
79  else if (rc == 0)
80  fprintf(stream,"%sbacktrace=[empty]",sep);
81  else
82  fprintf(stream,"%sbacktrace=[%s]",sep,buf);
83  }
84  fprintf(stream,"]");
85  }
86  else if (ttctx == 2) {
87  /* Just walk up the parent hierarchy. */
88  i = 0;
89  do {
90  if (likely(i > 0))
91  fprintf(stream,"%s",tsep);
92 
93  if (target_thread_snprintf(target,tthread->tid,buf,sizeof(buf),
94  ttdetail,sep,kvsep) < 0)
95  fprintf(stream,"%s[tid=%"PRIiTID"",tprefix,tthread->tid);
96  else
97  fprintf(stream,"%s[%s",tprefix,buf);
98 
99  if (bt) {
100  rc = target_unwind_snprintf(buf,sizeof(buf),target,tthread->tid,
102 ,");
103  if (rc < 0)
104  fprintf(stream,"%sbacktrace=[error!]",sep);
105  else if (rc == 0)
106  fprintf(stream,"%sbacktrace=[empty]",sep);
107  else
108  fprintf(stream,"%sbacktrace=[%s]",sep,buf);
109  }
110  fprintf(stream,"]");
111 
112  ++i;
113  tthread = target_lookup_thread(target,tthread->ptid);
114  }
115  while (tthread);
116  }
117  else if (ttctx == 3) {
118  if (target_thread_snprintf(target,tid,buf,sizeof(buf),
119  ttdetail,sep,kvsep) < 0)
120  fprintf(stream,"%s[tid=%"PRIiTID"",tprefix,tid);
121  else
122  fprintf(stream,"%s[%s",tprefix,buf);
123 
124  tids = target_list_available_tids(target);
125 
126  if (!tids) {
127  fprintf(stream,"]");
128  return;
129  }
130 
131  array_list_foreach(tids,i,tthread) {
132  if (tthread->tid == tid)
133  continue;
134 
135  fprintf(stream,"%s",tsep);
136 
137  if (target_thread_snprintf(target,tthread->tid,buf,sizeof(buf),
138  ttdetail,sep,kvsep) < 0)
139  fprintf(stream,"%s[tid=%"PRIiTID"",tprefix,tthread->tid);
140  else
141  fprintf(stream,"%s[%s",tprefix,buf);
142 
143  if (bt) {
144  rc = target_unwind_snprintf(buf,sizeof(buf),target,tthread->tid,
146 ,");
147  if (rc < 0)
148  fprintf(stream,"%sbacktrace=[error!]",sep);
149  else if (rc == 0)
150  fprintf(stream,"%sbacktrace=[empty]",sep);
151  else
152  fprintf(stream,"%sbacktrace=[%s]",sep,buf);
153  }
154  fprintf(stream,"]");
155  }
156  }
157 }
158 
159 result_t np_handler(struct probe *probe,tid_t tid,void *data,
160  struct probe *trigger,struct probe *base) {
161  struct np_status *nps = (struct np_status *)probe_priv(probe);
162 
163  if (NP_IS_MMAP(trigger,nps)) {
164  fprintf(stdout,
165  "RESULT:: (i:%d) np (30) NullPageUsageMmap"
166  " \"NULL Page Usage (mmap)!\""
167  " (mmap_violations=%d,",
169  }
170  else if (NP_IS_MPROTECT(trigger,nps)) {
171  fprintf(stdout,
172  "RESULT:: (i:%d) np (31) NullPageUsageMprotect"
173  " \"NULL Page Usage (mprotect)!\""
174  " (mprotect_violations=%d,",
176  }
177  else if (NP_IS_PGFAULT(trigger,nps)) {
178  fprintf(stdout,
179  "RESULT:: (i:%d) np (32) NullPageUsagePageFault"
180  " \"NULL Page Usage (Page Fault)!\""
181  " (mmap_violations=%d,",
183  }
184  else {
185  vwarn("trigger was not valid!? BUG!?\n");
186  return 0;
187  }
188 
189  print_thread_context(stdout,probe->target,tid,
190  nps->config->ttctx,nps->config->ttdetail,
191  1,";",":","thread=",",");
192  fputs(") ::RESULT\n",stdout);
193  fflush(stdout);
194 
195  return 0;
196 }
197 
199  return;
200 }
201 
202 int main(int argc,char **argv) {
203  target_status_t tstat;
204  struct target_spec *tspec;
205  char targetstr[128];
206  char *endptr = NULL;
207 
208  target_init();
209  atexit(target_fini);
210 
212 
213  memset(&npc,0,sizeof(npc));
214  npc.ttctx = 1;
215  npc.ttdetail = 0;
216 
217  tspec = target_argp_driver_parse_one(&np_argp,&npc,argc,argv,
219 
220  if (!tspec) {
221  verror("could not parse target arguments!\n");
222  exit(-1);
223  }
224 
225  target = target_instantiate(tspec,NULL);
226  if (!target) {
227  verror("could not instantiate target!\n");
228  exit(-1);
229  }
230  target_snprintf(target,targetstr,sizeof(targetstr));
231 
232  if (target_open(target)) {
233  fprintf(stderr,"could not open %s!\n",targetstr);
234  exit(-4);
235  }
236 
237  /* Install probes... */
238  np_probe = probe_np(target,&npc,np_handler,NULL,NULL);
239  if (!np_probe) {
240  verror("could not instantiate the null page usage meta-probe; aborting!\n");
241  cleanup_probes();
243  exit(-4);
244  }
245 
246  /*
247  * The target was paused after instantiation; we have to resume it
248  * now that we've registered probes.
249  */
250  target_resume(target);
251 
252  fprintf(stdout,"Starting Null Page Usage monitoring!\n");
253  fflush(stdout);
254 
255  while (1) {
256  tstat = target_monitor(target);
257  if (tstat == TSTATUS_PAUSED || tstat == TSTATUS_INTERRUPTED) {
258  fflush(stderr);
259  fflush(stdout);
260  vwarn("target %s interrupted at 0x%"PRIxREGVAL"; trying resume!\n",
261  targetstr,target_read_creg(target,TID_GLOBAL,CREG_IP));
262 
263  if (target_resume(target)) {
264  verror("could not resume target\n");
265  cleanup_probes();
267  exit(-16);
268  }
269  }
270  else if (tstat == TSTATUS_EXITING) {
271  fflush(stderr);
272  fflush(stdout);
273  if (np_probe) {
274  fprintf(stdout,"target %s exiting, printing final results...\n",
275  targetstr);
276 
278 
279  fprintf(stdout,"target %s exiting, removing probes safely...\n",
280  targetstr);
281 
282  probe_free(np_probe,1);
283  np_probe = NULL;
284  }
285 
286  if (target_resume(target)) {
287  verror("could not resume target!\n");
288  cleanup_probes();
290  exit(-16);
291  }
292  }
293  else if (tstat == TSTATUS_DONE) {
294  fflush(stderr);
295  fflush(stdout);
296  if (np_probe) {
297  fprintf(stdout,"target %s exited, printing final results...\n",
298  targetstr);
299 
301 
302  probe_free(np_probe,1);
303  np_probe = NULL;
304  }
305 
306  fprintf(stdout,"target %s exited, cleaning up.\n",targetstr);
307 
308  cleanup_probes();
310  goto out;
311  }
312  else {
313  fflush(stderr);
314  fflush(stdout);
315  if (np_probe) {
316  fprintf(stdout,
317  "target %s interrupted at 0x%"PRIxREGVAL
318  " -- bad status (%d), printing final results...\n",
319  targetstr,target_read_creg(target,TID_GLOBAL,CREG_IP),
320  tstat);
321 
323 
324  probe_free(np_probe,1);
325  np_probe = NULL;
326  }
327 
328  fprintf(stdout,
329  "target %s interrupted at 0x%"PRIxREGVAL
330  " -- bad status (%d), exiting\n",
331  targetstr,target_read_creg(target,TID_GLOBAL,CREG_IP),tstat);
332 
333  goto err;
334  }
335  }
336 
337  err:
338  fflush(stderr);
339  fflush(stdout);
340  cleanup_probes();
342 
343  out:
344  fflush(stderr);
345  fflush(stdout);
346  exit(0);
347 }
int target_thread_snprintf(struct target *target, tid_t tid, char *buf, int bufsiz, int detail, char *sep, char *kvsep)
Definition: target_api.c:1425
result_t np_handler(struct probe *probe, tid_t tid, void *data, struct probe *trigger, struct probe *base)
int ttctx
Definition: nullpage.h:31
int32_t tid_t
Definition: common.h:36
unsigned int pgfault_violations
Definition: nullpage.h:50
target_status_t
Definition: target_api.h:197
int target_unwind_snprintf(char *buf, int buflen, struct target *target, tid_t tid, target_unwind_style_t fstyle, char *frame_sep, char *ksep)
Definition: target.c:5482
struct target_spec * tspec
Definition: dumptarget.c:113
int ttdetail
Definition: nullpage.h:32
struct probe * np_probe
static uint64_t unsigned int i
void print_thread_context(FILE *stream, struct target *target, tid_t tid, int ttctx, int ttdetail, int bt, char *sep, char *kvsep, char *tprefix, char *tsep)
void target_init(void)
Definition: target.c:69
Definition: arch.h:74
int target_resume(struct target *target)
Definition: target_api.c:1012
void np_check_print_final_results(struct probe *probe)
#define NP_IS_MPROTECT(trigger, nps)
Definition: nullpage.h:55
#define likely(expr)
Definition: debugpred.h:102
int target_pause(struct target *target)
Definition: target_api.c:1027
#define NP_IS_MMAP(trigger, nps)
Definition: nullpage.h:54
int main(int argc, char **argv)
struct argp np_argp
Definition: nullpage_util.c:48
#define verror(format,...)
Definition: log.h:30
int target_install_default_sighandlers(void(*sighandler)(int signo, siginfo_t *siginfo, void *x))
Definition: target.c:240
void target_fini(void)
Definition: target.c:91
#define vwarn(format,...)
Definition: log.h:33
int target_snprintf(struct target *target, char *buf, int bufsiz)
Definition: target_api.c:829
#define array_list_foreach(alist, lpc, placeholder)
Definition: alist.h:371
void target_default_cleanup()
Definition: target.c:128
unsigned int mmap_violations
Definition: nullpage.h:48
int probe_free(struct probe *probe, int force)
Definition: probe.c:777
void * probe_priv(struct probe *probe)
Definition: probe.c:1951
Definition: probe.h:308
unsigned int mprotect_violations
Definition: nullpage.h:49
void sigh_cleanup_probes(int signo, siginfo_t *siginfo, void *x)
REGVAL target_read_creg(struct target *target, tid_t tid, common_reg_t reg)
Definition: target_api.c:1178
struct np_config * config
Definition: nullpage.h:36
#define NP_IS_PGFAULT(trigger, nps)
Definition: nullpage.h:56
struct array_list * target_list_available_tids(struct target *target)
Definition: target_api.c:1272
struct probe * probe_np(struct target *target, struct np_config *npc, probe_handler_t pre_handler, probe_handler_t post_handler, void *handler_data)
result_t
Definition: common.h:25
#define PRIiTID
Definition: common.h:37
struct target * target
Definition: probe.h:342
int target_open(struct target *target)
Definition: target_api.c:513
target_status_t target_monitor(struct target *target)
Definition: target_api.c:869
unsigned int total_violations
Definition: nullpage.h:51
void cleanup_probes()
struct target_spec * target_argp_driver_parse_one(struct argp *driver_parser, void *driver_state, int argc, char **argv, target_type_t target_types, int filter_quoted)
Definition: target.c:802
struct target * target_instantiate(struct target_spec *spec, struct evloop *evloop)
Definition: target_api.c:55
struct target_thread * target_lookup_thread(struct target *target, tid_t tid)
Definition: target.c:4023
#define TID_GLOBAL
Definition: target_api.h:145
struct np_config npc
#define PRIxREGVAL
Definition: common.h:72