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
spf.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013, 2014, 2015 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 "glib_wrapper.h"
29 #include "dwdebug.h"
30 #include "target_api.h"
31 #include "target.h"
32 #include "target_os.h"
33 
34 #include "probe_api.h"
35 #include "probe.h"
36 #include "alist.h"
37 #include "list.h"
38 
39 /*
40  * Private vdebug flags for LA_USER for us.
41  */
42 #define LF_U_CFG 1 << 1
43 #define LF_U_PROBE 1 << 2
44 
45 /*
46  * Types.
47  */
48 typedef enum {
59 
60 struct spf_action {
62 
63  union {
64  struct {
65  char rt;
66  char *tn;
67  int tid;
68  char *rv;
69  char *msg;
70  int ttctx;
71  int ttdetail;
72  int bt;
75  } report;
76  struct {
77  int ttctx;
78  int ttdetail;
79  } print;
80  struct {
81  long int retval;
82  } abort;
83  struct {
84  long int retval;
85  } exit;
86  struct {
87  char *id;
88  } enable;
89  struct {
90  char *id;
91  } disable;
92  struct {
93  char *id;
94  } remove;
95  struct {
96  int tid;
97  char *thid;
98  int overlay_levels;
100  } bt;
101  struct {
102  int tid;
103  char *thid;
104  char *sigdesc;
105  } signal;
106  };
107 };
108 
109 #define WHEN_PRE 0
110 #define WHEN_POST 1
111 
112 struct spf_filter {
113  char *id;
114 
115  char *srcfile;
116  char *symbol;
117  struct bsymbol *bsymbol;
118  /* When it's applied; pre or post. */
119  int when;
120  uint8_t disable:1;
121  /*
122  * symbol value regexps
123  */
125  /*
126  * tid, ptid, tidhier^, uid, gid, name, namehier^...
127  */
129  GSList *actions;
130 };
131 
132 struct spf_config {
134 };
135 
136 struct overlay_spec {
137  char *base_target_id;
139  struct target_spec *spec;
140 };
141 
143  int argc;
144  char **argv;
145  char *config_file;
150 };
151 
152 /*
153  * Globals.
154  */
155 GList *targets;
156 struct spf_config *config = NULL;
158 
159 GHashTable *sprobes = NULL;
160 GHashTable *fprobes = NULL;
161 
162 int needtodie = 0;
164 
166 
167 /* A few prototypes. */
168 struct spf_config *load_config_file(char *file);
169 int apply_config_file(struct spf_config *config);
170 void reload_config_file(void);
171 void spf_action_free(struct spf_action *spfa);
172 void spf_filter_free(struct spf_filter *spff);
173 void spf_config_free(struct spf_config *config);
174 
175 
177  GHashTableIter iter;
178  gpointer key;
179  struct probe *probe;
180  GList *t1;
181  struct target *target;
182 
183  v_g_list_foreach(targets,t1,target) {
184  target_pause(target);
185  }
186 
187  if (fprobes) {
188  g_hash_table_iter_init(&iter,fprobes);
189  while (g_hash_table_iter_next(&iter,
190  (gpointer)&key,
191  (gpointer)&probe)) {
192  probe_unregister(probe,1);
193  probe_free(probe,1);
194  }
195  g_hash_table_destroy(fprobes);
196  fprobes = NULL;
197  }
198  if (sprobes) {
199  g_hash_table_iter_init(&iter,sprobes);
200  while (g_hash_table_iter_next(&iter,
201  (gpointer)&key,
202  (gpointer)&probe)) {
203  probe_unregister(probe,1);
204  probe_free(probe,1);
205  }
206  g_hash_table_destroy(sprobes);
207  sprobes = NULL;
208  }
209 }
210 
212 
213 void sigh_cleanup_probes(int signo,siginfo_t *siginfo,void *x) {
214  if (sigismember(&exitset,signo)) {
215  cleanup_probes();
216  }
217 }
218 
219 void print_thread_context(FILE *stream,struct target *target,tid_t tid,
220  int ttctx,int ttdetail,int bt,int overlay_levels,
221  char *overlay_debuginfo_prefix,char *sep,char *kvsep,
222  char *tprefix,char *tsep) {
223  struct target_thread *tthread;
224  char buf[8192];
225  struct array_list *tids;
226  int i,j;
227  int rc;
228  int didmaintid = 0;
229  tid_t ttid;
230  struct target *overlay;
231  struct array_list *otl;
232  struct target_spec *ospec;
233 
234  if (ttctx == 0)
235  return;
236  else if (ttctx == 1) {
237  tids = array_list_create(1);
238  array_list_append(tids,(void *)(uintptr_t)tid);
239  }
240  else if (ttctx == 2) {
241  tids = array_list_create(8);
242  /* Just walk up the parent hierarchy. */
243  ttid = tid;
244  while (1) {
245  tthread = target_lookup_thread(target,ttid);
246  if (!tthread)
247  break;
248  array_list_append(tids,(void *)(uintptr_t)ttid);
249  ttid = tthread->ptid;
250  }
251  }
252  else if (ttctx == 3) {
253  tids = target_list_available_tids(target);
254  /* Make sure selected tid is first; skip it later. */
255  if (!tids)
256  tids = array_list_create(1);
257  array_list_prepend(tids,(void *)(uintptr_t)tid);
258  }
259  else
260  return;
261 
262  array_list_foreach_fakeptr_t(tids,i,ttid,uintptr_t) {
263  tthread = target_lookup_thread(target,ttid);
264  if (!tthread)
265  continue;
266 
267  if (tthread->tid == tid && didmaintid)
268  continue;
269  else if (tthread->tid == tid)
270  didmaintid = 1;
271 
272  fprintf(stream,"%s",tsep);
273 
274  if (target_thread_snprintf(target,tthread->tid,buf,sizeof(buf),
275  ttdetail,sep,kvsep) < 0)
276  fprintf(stream,"%s[tid=%"PRIiTID"",tprefix,tthread->tid);
277  else
278  fprintf(stream,"%s[%s",tprefix,buf);
279 
280  if (bt) {
281  rc = target_unwind_snprintf(buf,sizeof(buf),target,tthread->tid,
283  if (rc < 0)
284  fprintf(stream,"%sbacktrace=[error!]",sep);
285  else if (rc == 0)
286  fprintf(stream,"%sbacktrace=[empty]",sep);
287  else
288  fprintf(stream,"%sbacktrace=[%s]",sep,buf);
289  }
290 
291  fprintf(stream,"]");
292 
293  /*
294  * Handle overlay levels! Woot!
295  */
296  otl = array_list_create(8);
297  overlay = target;
298  ttid = tthread->tid;
299  while (overlay_levels != 0) {
300  ospec = target_build_default_overlay_spec(overlay,ttid);
301  if (!ospec)
302  break;
303 
304  if (overlay_debuginfo_prefix)
305  ospec->debugfile_root_prefix = strdup(overlay_debuginfo_prefix);
306 
307  overlay = target_instantiate_overlay(overlay,ttid,ospec);
308  if (!overlay)
309  break;
310 
311  target_open(overlay);
312 
313  fprintf(stream,"%s",tsep);
314 
315  if (target_thread_snprintf(overlay,ttid,buf,sizeof(buf),
316  ttdetail,sep,kvsep) < 0)
317  fprintf(stream,"%s[overlay=%s%stid=%"PRIiTID"",
318  tprefix,overlay->name,sep,ttid);
319  else
320  fprintf(stream,"%s[overlay=%s%s%s",
321  tprefix,overlay->name,sep,buf);
322 
323  if (bt) {
324  rc = target_unwind_snprintf(buf,sizeof(buf),overlay,ttid,
326  "|",",");
327  if (rc < 0)
328  fprintf(stream,"%sbacktrace=[error!]",sep);
329  else if (rc == 0)
330  fprintf(stream,"%sbacktrace=[empty]",sep);
331  else
332  fprintf(stream,"%sbacktrace=[%s]",sep,buf);
333  }
334 
335  fprintf(stream,"]");
336 
337  --overlay_levels;
338 
339  array_list_prepend(otl,overlay);
340  }
341 
342  array_list_foreach(otl,j,overlay) {
343  target_close(overlay);
344  target_finalize(overlay);
345  }
346 
347  array_list_free(otl);
348  otl = NULL;
349  }
350 
351  array_list_free(tids);
352 }
353 
354 void spf_backtrace(struct target *t,tid_t ctid,char *tiddesc,
355  int overlay_levels,char *overlay_debuginfo_prefix) {
356  struct array_list *tids;
357  tid_t tid;
358  int i;
359  tid_t stid = -1;
360  struct target_thread *tthread;
361  char *endptr = NULL;
362  int rc;
363  char buf[8192];
364  struct target *overlay;
365  struct array_list *otl;
366  struct target_spec *ospec;
367 
368  if (tiddesc) {
369  stid = (int)strtol(tiddesc,&endptr,10);
370  if (tiddesc == endptr)
371  stid = -1;
372  else
373  tiddesc = NULL;
374  }
375  else
376  stid = -1;
377 
378  /*
379  * If stid == 0 or tiddesc, do them all.
380  *
381  * If it == -1 && !tiddesc, do ctid.
382  *
383  * If it >= 0, do that one.
384  */
385 
386  if (stid == -1 && !tiddesc) {
387  tids = array_list_create(1);
388  array_list_append(tids,(void *)(uintptr_t)ctid);
389 
390  printf("Backtracing target '%s' (current thread %d):\n\n",t->name,ctid);
391  }
392  else if (stid > 0) {
393  tids = array_list_create(1);
394  array_list_append(tids,(void *)(uintptr_t)stid);
395 
396  printf("Backtracing target '%s' (thread %d):\n\n",t->name,stid);
397  }
398  else if (tiddesc) {
399  tids = target_list_tids(t);
400 
401  printf("Backtracing target '%s' (thread name %s):\n\n",t->name,tiddesc);
402  }
403  else {
404  tids = target_list_tids(t);
405 
406  printf("Backtracing target '%s' (all threads):\n\n",t->name);
407  }
408 
409  array_list_foreach_fakeptr_t(tids,i,tid,uintptr_t) {
410  tthread = target_lookup_thread(t,tid);
411  if (!tthread)
412  continue;
413 
414  if ((tiddesc && !tthread->name)
415  || (tiddesc && strcmp(tiddesc,tthread->name)))
416  continue;
417 
418  rc = target_unwind_snprintf(buf,sizeof(buf),t,tid,
419  TARGET_UNWIND_STYLE_GDB,"\n",",");
420  if (rc < 0)
421  fprintf(stdout,"\ntarget %s thread %"PRIiTID": (error!)\n",
422  t->name,tid);
423  else if (rc == 0)
424  fprintf(stdout,"\ntarget %s thread %"PRIiTID": (nothing)\n",
425  t->name,tid);
426  else
427  fprintf(stdout,"\ntarget %s thread %"PRIiTID": \n%s\n",
428  t->name,tid,buf);
429 
430  if (overlay_levels == 0)
431  continue;
432 
433  /*
434  * Handle overlay levels!
435  */
436  otl = array_list_create(8);
437  overlay = t;
438  while (overlay_levels != 0) {
439  ospec = target_build_default_overlay_spec(overlay,tid);
440  if (!ospec)
441  break;
442 
443  /* Try read-only, because we don't want any of the extra gunk */
444  ospec->read_only = 1;
445 
446  if (overlay_debuginfo_prefix)
447  ospec->debugfile_root_prefix = strdup(overlay_debuginfo_prefix);
448 
449  overlay = target_instantiate_overlay(overlay,tid,ospec);
450  if (!overlay)
451  break;
452 
453  target_open(overlay);
454 
455  rc = target_unwind_snprintf(buf,sizeof(buf),overlay,tid,
456  TARGET_UNWIND_STYLE_GDB,"\n",",");
457  if (rc < 0)
458  fprintf(stdout,"\ntarget %s thread %"PRIiTID": (error!)\n",
459  overlay->name,tid);
460  else if (rc == 0)
461  fprintf(stdout,"\ntarget %s thread %"PRIiTID": (nothing)\n",
462  overlay->name,tid);
463  else
464  fprintf(stdout,"\ntarget %s thread %"PRIiTID": \n%s\n",
465  overlay->name,tid,buf);
466 
467  --overlay_levels;
468 
469  array_list_prepend(otl,overlay);
470  }
471 
472  array_list_foreach(otl,i,overlay) {
473  target_close(overlay);
474  target_finalize(overlay);
475  }
476 
477  array_list_free(otl);
478  otl = NULL;
479  }
480 
481  fputs("\n",stdout);
482  fflush(stdout);
483 }
484 
485 int spf_signal(struct target *t,tid_t ctid,char *tiddesc,char *sigdesc) {
486  struct array_list *tids;
487  tid_t tid;
488  int i;
489  tid_t stid = -1;
490  struct target_thread *tthread;
491  char *endptr = NULL;
492  int rc;
493  int signo;
494 
495  signo = target_os_signal_from_name(t,sigdesc);
496 
497  if (tiddesc) {
498  stid = (int)strtol(tiddesc,&endptr,10);
499  if (tiddesc == endptr)
500  stid = -1;
501  else
502  tiddesc = NULL;
503  }
504  else
505  stid = -1;
506 
507  /*
508  * If stid == 0 or tiddesc, do them all.
509  *
510  * If it == -1 && !tiddesc, do ctid.
511  *
512  * If it >= 0, do that one.
513  */
514 
515  if (stid == -1 && !tiddesc) {
516  tids = array_list_create(1);
517  array_list_append(tids,(void *)(uintptr_t)ctid);
518 
519  printf("Signaling target '%s' (current thread %d):\n\n",t->name,ctid);
520  }
521  else if (stid > 0) {
522  tids = array_list_create(1);
523  array_list_append(tids,(void *)(uintptr_t)stid);
524 
525  printf("Signaling target '%s' (thread %d):\n\n",t->name,stid);
526  }
527  else if (tiddesc) {
528  tids = target_list_tids(t);
529 
530  printf("Signaling target '%s' (thread name %s):\n\n",t->name,tiddesc);
531  }
532  else {
533  tids = target_list_tids(t);
534 
535  printf("Signaling target '%s' (all threads):\n\n",t->name);
536  }
537 
538  array_list_foreach_fakeptr_t(tids,i,tid,uintptr_t) {
539  tthread = target_lookup_thread(t,tid);
540  if (!tthread)
541  continue;
542 
543  if ((tiddesc && !tthread->name)
544  || (tiddesc && strcmp(tiddesc,tthread->name)))
545  continue;
546 
547  rc = target_os_signal_enqueue(t,tid,signo,NULL);
548  if (rc < 0)
549  fprintf(stdout,"thread %"PRIiTID": (error!)\n",tid);
550  else if (rc == 0)
551  fprintf(stdout,"thread %"PRIiTID": success\n",tid);
552  else
553  fprintf(stdout,"thread %"PRIiTID": unknown status %d\n",tid,rc);
554  }
555 
556  fflush(stdout);
557 
558  return 0;
559 }
560 
561 result_t handler(int when,struct probe *probe,tid_t tid,void *data,
562  struct probe *trigger,struct probe *base) {
563  GHashTableIter iter;
564  gpointer kp,vp;
565  char vstrbuf_static[1024];
566  char *vstrbuf = NULL;
567  char *vstrbuf_dynamic = NULL;
568  int vstrbuf_dynamic_size = 0;
569  struct value *v;
570  GHashTable *vt;
571  struct bsymbol *bsymbol;
572  struct symbol *symbol;
573  int i,j;
574  int rc;
575  struct spf_filter *spff = (struct spf_filter *)data;
576  GSList *gsltmp;
577  struct spf_action *spfa;
578  struct probe *fprobe;
579  result_t retval = RESULT_SUCCESS;
580  struct target *btt,*st;
581 
582  /*
583  * Do all the actions.
584  */
585  v_g_slist_foreach(spff->actions,gsltmp,spfa) {
586  if (spfa->atype == SPF_ACTION_ABORT) {
587  /*
588  * Action has to be registered on the base probe!!
589  */
590  struct action *action = action_return(spfa->abort.retval);
591  if (!action) {
592  verror("probe %s: could not create action on probe %s !\n",
593  probe_name(probe),probe_name(base));
594  }
595  else if (action_sched(base,action,ACTION_ONESHOT,NULL,NULL)) {
596  verror("probe %s: could not schedule action on probe %s!\n",
597  probe_name(probe),probe_name(base));
598  action_release(action);
599  }
600  else {
602  "probe %s: scheduled return action on probe %s\n",
603  probe_name(probe),probe_name(base));
604  action_release(action);
605  }
606  }
607  else if (spfa->atype == SPF_ACTION_ENABLE) {
608  /* Check if it's us. No need to waste a hashtable lookup. */
609  if (strcmp(spfa->enable.id,probe_name(probe)) == 0)
610  fprobe = probe;
611  else
612  fprobe = (struct probe *) \
613  g_hash_table_lookup(fprobes,spfa->enable.id);
614  if (!fprobe) {
615  vwarn("probe %s: cannot enable nonexisting filter probe %s!\n",
616  probe_name(probe),spfa->enable.id);
617  }
618  else {
619  probe_enable(fprobe);
621  "probe %s: enabled filter probe %s\n",
622  probe_name(probe),spfa->enable.id);
623  }
624  }
625  else if (spfa->atype == SPF_ACTION_DISABLE) {
626  /* Check if it's us. No need to waste a hashtable lookup. */
627  if (strcmp(spfa->disable.id,probe_name(probe)) == 0)
628  fprobe = probe;
629  else
630  fprobe = (struct probe *) \
631  g_hash_table_lookup(fprobes,spfa->disable.id);
632  if (!fprobe) {
633  vwarn("probe %s: cannot enable nonexisting filter probe %s!\n",
634  probe_name(probe),spfa->disable.id);
635  }
636  else {
637  probe_disable(fprobe);
638  vdebug(5,LA_USER,LF_U_PROBE,"probe %s: disabled probe %s\n",
639  probe_name(probe),spfa->disable.id);
640  }
641  }
642  else if (spfa->atype == SPF_ACTION_REMOVE) {
643  /* Check if it's us -- to remove self we have to return special! */
644  if (strcmp(spfa->remove.id,probe_name(probe)) == 0) {
645  vdebug(5,LA_USER,LF_U_PROBE,"probe %s: removing self!\n",
646  probe_name(probe));
647  retval = RESULT_ABORT;
648  }
649  else {
650  fprobe = (struct probe *) \
651  g_hash_table_lookup(fprobes,spfa->remove.id);
652  if (!fprobe) {
653  vwarn("probe %s: cannot remove nonexisting filter probe %s!\n",
654  probe_name(probe),spfa->remove.id);
655  }
656  else {
657  probe_free(fprobe,0);
658  vdebug(5,LA_USER,LF_U_PROBE,"probe %s: removed probe %s\n",
659  probe_name(probe),spfa->remove.id);
660  }
661  }
662  }
663  else if (spfa->atype == SPF_ACTION_EXIT) {
664  /*
665  * Have to schedule a monitor interrupt to exit!
666  */
667  if (spfa->exit.retval == -69) {
668  cleanup_probes();
669  exit(-69);
670  }
671 
672  /*
673  * We don't need to actually interrupt the monitor, though,
674  * because we're in a handler -- so some driver is handling
675  * us.
676  */
678  needtodie = 1;
679  needtodie_exitcode = spfa->exit.retval;
680  vdebug(5,LA_USER,LF_U_PROBE,"probe %s: scheduled exit with %d!\n",
681  probe_name(probe),spfa->exit.retval);
682  }
683  else if (spfa->atype == SPF_ACTION_REPORT) {
684  ++result_counter;
685 
686  bsymbol = probe->bsymbol;
687  symbol = bsymbol_get_symbol(bsymbol);
688 
689  vt = probe_value_get_table(trigger,tid);
690  if (!vt) {
691  vwarn("probe %s: could not get values from probe %s"
692  " (tid %"PRIiTID")!\n",
693  probe_name(probe),probe_name(trigger),tid);
694  }
695 
696  fflush(stderr);
697  fflush(stdout);
698 
699  fprintf(stdout,"RESULT:: (%c:%d) %s (%d) %s %s (",
700  spfa->report.rt,result_counter,
701  spfa->report.tn ? spfa->report.tn : "",
702  spfa->report.tid,spfa->report.rv ? spfa->report.rv : "",
703  spfa->report.msg ? spfa->report.msg : "\"\"");
704  /* Now print the values... */
705  if (vt) {
706  i = 0;
707  g_hash_table_iter_init(&iter,vt);
708  while (g_hash_table_iter_next(&iter,&kp,&vp)) {
709  if (i > 0)
710  fprintf(stdout,",");
711  v = (struct value *)vp;
712  if (v) {
713  rc = value_snprintf(v,vstrbuf_static,
714  sizeof(vstrbuf_static));
715  vstrbuf = vstrbuf_static;
716  if (rc >= (int)sizeof(vstrbuf_static)) {
717  vstrbuf_dynamic_size = rc + 1;
718  vstrbuf_dynamic = malloc(vstrbuf_dynamic_size);
719  rc = value_snprintf(v,vstrbuf_dynamic,
720  vstrbuf_dynamic_size);
721  vstrbuf = vstrbuf_dynamic;
722  }
723 
724  if (rc > 0) {
725  int unprintable = 0;
726  for (j = 0; vstrbuf[j] != '\0'; ++j) {
727  if (!isgraph(vstrbuf[j]) && !isspace(vstrbuf[j])) {
728  unprintable = 1;
729  break;
730  }
731  }
732 
733  if (unprintable) {
734  vwarn("unprintable raw value for key %s = 0x",
735  (char *)kp);
736  for (j = 0; vstrbuf[j] != '\0'; ++j) {
737  vwarnc("%hhx",vstrbuf[j]);
738  }
739  vwarnc("\n");
740 
741  fprintf(stdout,"%s=??",(char *)kp);
742  }
743  else {
744  fprintf(stdout,"%s=%s",(char *)kp,vstrbuf);
745  }
746  }
747  else
748  fprintf(stdout,"%s=?",(char *)kp);
749 
750  if (vstrbuf_dynamic) {
751  free(vstrbuf_dynamic);
752  vstrbuf_dynamic = NULL;
753  vstrbuf_dynamic_size = 0;
754  }
755  }
756  else
757  fprintf(stdout,"%s=?",(char *)kp);
758  ++i;
759  }
760  }
761  fputs(",",stdout);
762  print_thread_context(stdout,bsymbol->region->space->target,tid,
763  spfa->report.ttctx,spfa->report.ttdetail,
764  spfa->report.bt,spfa->report.overlay_levels,
765  spfa->report.overlay_debuginfo_prefix,
766  ";",":","thread=",",");
767  fprintf(stdout,") ::RESULT\n");
768  fflush(stdout);
769  }
770  else if (spfa->atype == SPF_ACTION_PRINT) {
771  bsymbol = probe->bsymbol;
772  symbol = bsymbol_get_symbol(bsymbol);
773 
774  vt = probe_value_get_table(trigger,tid);
775  if (!vt) {
776  vwarn("probe %s: could not get values from probe %s"
777  " (tid %"PRIiTID")!\n",
778  probe_name(probe),probe_name(trigger),tid);
779  }
780 
781  fflush(stderr);
782  fflush(stdout);
783 
785  fprintf(stdout,"%s (",symbol_get_name(symbol));
786  if (vt) {
787  i = 0;
788  g_hash_table_iter_init(&iter,vt);
789  while (g_hash_table_iter_next(&iter,&kp,&vp)) {
790  if (strcmp((char *)kp,PROBE_VALUE_NAME_RETURN) == 0)
791  continue;
792  if (i > 0)
793  fprintf(stdout,",");
794  v = (struct value *)vp;
795  if (v) {
796  rc = value_snprintf(v,vstrbuf_static,
797  sizeof(vstrbuf_static));
798  vstrbuf = vstrbuf_static;
799  if (rc >= (int)sizeof(vstrbuf_static)) {
800  vstrbuf_dynamic_size = rc + 1;
801  vstrbuf_dynamic = malloc(vstrbuf_dynamic_size);
802  rc = value_snprintf(v,vstrbuf_dynamic,
803  vstrbuf_dynamic_size);
804  vstrbuf = vstrbuf_dynamic;
805  }
806 
807  if (rc > 0)
808  fprintf(stdout,"%s = %s",(char *)kp,vstrbuf);
809  else
810  fprintf(stdout,"%s = ?",(char *)kp);
811 
812  if (vstrbuf_dynamic) {
813  free(vstrbuf_dynamic);
814  vstrbuf_dynamic = NULL;
815  vstrbuf_dynamic_size = 0;
816  }
817  }
818  else
819  fprintf(stdout,"%s = ?",(char *)kp);
820  ++i;
821  }
822  }
823  else {
825  fprintf(stdout,"?");
826  else
827  fprintf(stdout," = ?");
828  }
830  fprintf(stdout,")");
831  if (vt) {
832  v = (struct value *) \
833  g_hash_table_lookup(vt,PROBE_VALUE_NAME_RETURN);
834  if (v) {
835  rc = value_snprintf(v,vstrbuf_static,
836  sizeof(vstrbuf_static));
837  vstrbuf = vstrbuf_static;
838  if (rc >= (int)sizeof(vstrbuf_static)) {
839  vstrbuf_dynamic_size = rc + 1;
840  vstrbuf_dynamic = malloc(vstrbuf_dynamic_size);
841  rc = value_snprintf(v,vstrbuf_dynamic,
842  vstrbuf_dynamic_size);
843  vstrbuf = vstrbuf_dynamic;
844  }
845 
846  if (rc > 0)
847  fprintf(stdout," = %s",vstrbuf_static);
848  else
849  fprintf(stdout," = ?");
850 
851  if (vstrbuf_dynamic) {
852  free(vstrbuf_dynamic);
853  vstrbuf_dynamic = NULL;
854  vstrbuf_dynamic_size = 0;
855  }
856  }
857  }
858  }
859  fputs(" ",stdout);
860  print_thread_context(stdout,bsymbol->region->space->target,tid,
861  spfa->print.ttctx,spfa->print.ttdetail,
862  0,0,NULL,NULL,NULL,"",",");
863  fputs("\n",stdout);
864  fflush(stdout);
865  }
866  else if (spfa->atype == SPF_ACTION_BT) {
867  if (spfa->bt.tid > 1) {
868  btt = target_lookup_target_id(spfa->bt.tid);
869  if (!btt) {
870  verror("no existing target with id '%d'!\n",spfa->bt.tid);
871  return RESULT_SUCCESS;
872  }
873  }
874  else
875  btt = probe->target;
876 
877  spf_backtrace(btt,tid,spfa->bt.thid,spfa->bt.overlay_levels,
878  spfa->bt.overlay_debuginfo_prefix);
879  }
880  else if (spfa->atype == SPF_ACTION_SIGNAL) {
881  if (spfa->signal.tid > 1) {
882  st = target_lookup_target_id(spfa->signal.tid);
883  if (!st) {
884  verror("no existing target with id '%d'!\n",
885  spfa->signal.tid);
886  return RESULT_SUCCESS;
887  }
888  }
889  else
890  st = probe->target;
891 
892  spf_signal(st,tid,spfa->signal.thid,spfa->signal.sigdesc);
893  }
894  else {
895  verror("probe %s: bad action type %d -- BUG!\n",
896  probe_name(probe),spfa->atype);
897  }
898  }
899 
900  return retval;
901 }
902 
903 result_t pre_handler(struct probe *probe,tid_t tid,void *data,
904  struct probe *trigger,struct probe *base) {
905  return handler(WHEN_PRE,probe,tid,data,trigger,base);
906 }
907 
908 result_t post_handler(struct probe *probe,tid_t tid,void *data,
909  struct probe *trigger,struct probe *base) {
910  return handler(WHEN_POST,probe,tid,data,trigger,base);
911 }
912 
913 /*
914  * This just makes sure values get loaded at the appropriate phases of
915  * the value probes so they are always available even if the probe is
916  * pre/post.
917  */
918 result_t null_handler(struct probe *probe,tid_t tid,void *data,
919  struct probe *trigger,struct probe *base) {
920  probe_value_get_table(trigger,tid);
921  return RESULT_SUCCESS;
922 }
923 
924 #define __TARGET_OVERLAY 0x200000
925 #define SPF_CONFIGFILE_FATAL 0x200001
926 #define SPF_OS_SYSCALL_PROBES 0x200002
927 
928 struct argp_option spf_argp_opts[] = {
929  { "overlay",__TARGET_OVERLAY,"[<target_id>:]<thread_name_or_id>:<spec_opts>",0,"Lookup name or id as an overlay target once the main target is instantiated, and try to open it. All dumptarget options then apply to the overlay.",0 },
930  { "config-file",'C',"<FILE>",0,"An SPF config file.",0 },
931  { "config-file-fatal",SPF_CONFIGFILE_FATAL,NULL,0,
932  "Make errors while applying runtime updates (via USR2) to the config file fatal.",0 },
933  { "use-os-syscall-probes",SPF_OS_SYSCALL_PROBES,NULL,0,
934  "Try to use target_os_syscall probes if symbol is a syscall and target is an OS.",0 },
935  { 0,0,0,0,0,0 },
936 };
937 
938 error_t spf_argp_parse_opt(int key,char *arg,struct argp_state *state) {
939  struct spf_argp_state *opts = \
940  (struct spf_argp_state *)target_argp_driver_state(state);
941 
942  switch (key) {
943  case ARGP_KEY_ARG:
944  return ARGP_ERR_UNKNOWN;
945  case ARGP_KEY_ARGS:
946  /* Eat all the remaining args. */
947  if (state->quoted > 0)
948  opts->argc = state->quoted - state->next;
949  else
950  opts->argc = state->argc - state->next;
951  if (opts->argc > 0) {
952  opts->argv = calloc(opts->argc,sizeof(char *));
953  memcpy(opts->argv,&state->argv[state->next],opts->argc*sizeof(char *));
954  state->next += opts->argc;
955  }
956  return 0;
957  case ARGP_KEY_INIT:
959  return 0;
960  case ARGP_KEY_END:
961  case ARGP_KEY_NO_ARGS:
962  case ARGP_KEY_SUCCESS:
963  return 0;
964  case ARGP_KEY_ERROR:
965  case ARGP_KEY_FINI:
966  return 0;
968  opts->config_file_fatal = 1;
969  break;
971  opts->use_os_syscall_probes = 1;
972  break;
973  case 'C':
974  opts->config_file = arg;
975  break;
976 
977  default:
978  return ARGP_ERR_UNKNOWN;
979  }
980 
981  return 0;
982 }
983 
984 struct argp spf_argp = {
985  spf_argp_opts,spf_argp_parse_opt,NULL,NULL,NULL,NULL,NULL,
986 };
987 
988 int main(int argc,char **argv) {
989  int i;
990  struct bsymbol *bsymbol;
991  struct probe *sprobe, *fprobe;
992  char *name, *context;
993  char *str;
994  char namebuf[128];
995  struct target_nv_filter *pre_pf, *post_pf;
996  char *pre_filter, *post_filter;
997  struct target_os_syscall *syscall;
998 
999  struct target_spec *primary_target_spec = NULL;
1000  GList *base_target_specs = NULL;
1001  GList *overlay_target_specs = NULL;
1002  struct target *target;
1003  int rc;
1004  struct evloop *evloop;
1005  GList *t1;
1006 
1007  target_init();
1008  atexit(target_fini);
1009 
1010  /*
1011  * We need to handle SIGUSR1, SIGUSR2, and SIGHUP specially so we
1012  * can reload our config file as necessary.
1013  */
1014  sigemptyset(&ignored);
1015  sigemptyset(&exitset);
1016  sigemptyset(&interrupt);
1017 
1018  sigaddset(&exitset,SIGINT);
1019  sigaddset(&exitset,SIGALRM);
1020  sigaddset(&exitset,SIGQUIT);
1021  sigaddset(&exitset,SIGILL);
1022  sigaddset(&exitset,SIGABRT);
1023  sigaddset(&exitset,SIGFPE);
1024  sigaddset(&exitset,SIGSEGV);
1025  sigaddset(&exitset,SIGPIPE);
1026  sigaddset(&exitset,SIGTERM);
1027  sigaddset(&exitset,SIGBUS);
1028  sigaddset(&exitset,SIGXCPU);
1029  sigaddset(&exitset,SIGXFSZ);
1030 
1031  sigaddset(&interrupt,SIGUSR1);
1032  sigaddset(&interrupt,SIGUSR2);
1033  sigaddset(&interrupt,SIGHUP);
1034 
1037 
1038  memset(&opts,0,sizeof(opts));
1039  rc = target_argp_driver_parse(&spf_argp,&opts,argc,argv,
1042  &primary_target_spec,&base_target_specs,
1043  &overlay_target_specs);
1044 
1045  if (rc) {
1046  verror("could not parse target arguments!\n");
1047  exit(-1);
1048  }
1049 
1050  if (opts.config_file) {
1051  config = load_config_file(opts.config_file);
1052  if (!config) {
1053  verror("could not read config file %s!\n",opts.config_file);
1054  exit(-11);
1055  }
1056  }
1057 
1058  evloop = evloop_create(NULL);
1059 
1060  targets = target_instantiate_and_open(primary_target_spec,
1061  base_target_specs,overlay_target_specs,
1062  evloop,NULL);
1063  if (!targets) {
1064  verror("could not instantiate and open targets!\n");
1065  exit(-1);
1066  }
1067 
1068  /*
1069  * Setup probes from command line or load config file.
1070  */
1071  sprobes = g_hash_table_new(g_direct_hash,g_direct_equal);
1072  fprobes = g_hash_table_new(g_direct_hash,g_direct_equal);
1073 
1075  v_g_list_foreach(targets,t1,target) {
1076  if (target->personality != TARGET_PERSONALITY_OS)
1077  continue;
1078 
1079  if (target_os_syscall_table_load(target))
1080  vwarn("could not load the syscall table for target %s;"
1081  " target_os_syscall probes will not be available!\n",
1082  target->name);
1083  }
1084  }
1085 
1086  if (opts.argc > 0) {
1087  for (i = 0; i < opts.argc; ++i) {
1088  pre_filter = post_filter = context = NULL;
1089  name = str = opts.argv[i];
1090  while (*str != '\0') {
1091  if (*str == ':' && *(str+1) == ':') {
1092  *str = '\0';
1093  str += 2;
1094  break;
1095  }
1096  ++str;
1097  }
1098  if (*str != '\0') {
1099  if (*str == ':')
1100  pre_filter = NULL;
1101  else
1102  pre_filter = str;
1103  }
1104  while (*str != '\0') {
1105  if (*str == ':' && *(str+1) == ':') {
1106  *str = '\0';
1107  str += 2;
1108  break;
1109  }
1110  ++str;
1111  }
1112  if (*str != '\0') {
1113  if (*str == ':')
1114  post_filter = NULL;
1115  else
1116  post_filter = str;
1117  }
1118  while (*str != '\0') {
1119  if (*str == ':' && *(str+1) == ':') {
1120  *str = '\0';
1121  str += 2;
1122  break;
1123  }
1124  ++str;
1125  }
1126  if (*str != '\0')
1127  context = str;
1128 
1129  sprobe = (struct probe *)g_hash_table_lookup(sprobes,name);
1130  if (!sprobe) {
1131  /*
1132  * Create a probe on that symbol:
1133  */
1134 
1135  bsymbol = NULL;
1136  v_g_list_foreach(targets,t1,target) {
1138  && target->personality == TARGET_PERSONALITY_OS)
1139  syscall = target_os_syscall_lookup_name(target,name);
1140  else
1141  syscall = NULL;
1142  if (syscall) {
1143  sprobe = \
1144  target_os_syscall_probe(target,TID_GLOBAL,syscall,
1147  NULL);
1148  if (!sprobe) {
1149  verror("could not place syscall value probe on %s;"
1150  " aborting!\n",name);
1151  rc = -5;
1152  goto exit;
1153  }
1154  else
1155  break;
1156  }
1157  else {
1158  bsymbol = target_lookup_sym(target,name,NULL,NULL,
1160  if (!bsymbol)
1161  continue;
1162 
1163  sprobe =
1165  TID_GLOBAL,bsymbol,
1168  NULL);
1169  if (!sprobe) {
1170  verror("could not place value probe on %s;"
1171  " aborting!\n",name);
1172  rc = -3;
1173  goto exit;
1174  }
1175  else
1176  break;
1177  }
1178  }
1179 
1180  if (!sprobe) {
1181  verror("could not probe symbol %s; aborting!\n",name);
1182  rc = -3;
1183  goto exit;
1184  }
1185  else
1186  g_hash_table_insert(sprobes,name,sprobe);
1187  }
1188 
1189  /* Create either an empty filter probe or parse the filter! */
1190  if (pre_filter) {
1191  pre_pf = target_nv_filter_parse(pre_filter);
1192  if (!pre_pf) {
1193  verror("could not parse pre_filter '%s'!\n",pre_filter);
1194  rc = -4;
1195  goto exit;
1196  }
1197  }
1198  else
1199  pre_pf = NULL;
1200  if (post_filter) {
1201  post_pf = target_nv_filter_parse(post_filter);
1202  if (!post_pf) {
1203  verror("could not parse post_filter '%s'!\n",post_filter);
1204  rc = -4;
1205  goto exit;
1206  }
1207  }
1208  else
1209  post_pf = NULL;
1210 
1211  snprintf(namebuf,sizeof(namebuf),"filter_%s_%d",name,i);
1212  fprobe = probe_create_filtered(sprobe->target,TID_GLOBAL,NULL,namebuf,
1213  pre_handler,pre_pf,
1214  post_handler,post_pf,NULL,NULL,0,1);
1215 
1216  probe_register_source(fprobe,sprobe);
1217 
1218  g_hash_table_insert(fprobes,namebuf,fprobe);
1219  }
1220  }
1221  else if (!opts.config_file) {
1222  /* Try the default config file. */
1223  if (access("spf.conf",R_OK)) {
1224  verror("Must supply some symbols to probe!\n");
1225  rc = -5;
1226  goto exit;
1227  }
1228  else {
1229  opts.config_file = strdup("spf.conf");
1230 
1231  config = load_config_file(opts.config_file);
1232  if (!config) {
1233  verror("could not read default config file %s!\n",
1234  opts.config_file);
1235  rc = -11;
1236  goto exit;
1237  }
1238  }
1239  }
1240 
1241  /* Now apply the config file. Always make the first application fatal. */
1242  int oldfatal = opts.config_file_fatal;
1243  opts.config_file_fatal = 1;
1244  if (apply_config_file(config)) {
1245  verror("could not install config file %s!\n",opts.config_file);
1246  rc = -12;
1247  goto exit;
1248  }
1249  opts.config_file_fatal = oldfatal;
1250 
1251  if (g_hash_table_size(sprobes) == 0) {
1252  verror("No symbols to probe; exiting!\n");
1253  rc = -1;
1254  goto exit;
1255  }
1256 
1257  /*
1258  * The targets were paused after instantiation; we have to resume them
1259  * now that we've registered probes.
1260  */
1261  v_g_list_foreach(targets,t1,target) {
1262  target_resume(target);
1263  }
1264 
1265  fprintf(stdout,"Starting Symbol Probe Filtering!\n");
1266  fflush(stdout);
1267 
1268  fprintf(stdout,"Starting thread watch loop!\n");
1269  fflush(stdout);
1270 
1271  while (1) {
1272  tid_t tid = 0;
1273  struct target *t;
1274  target_status_t tstat;
1275  char *tname;
1276  siginfo_t siginfo;
1277 
1278  rc = target_monitor_evloop(evloop,NULL,&t,&tstat);
1279 
1280  /*
1281  * Did we get interrupted safely? We need to check if we were
1282  * told to either die, or if we need to reload the config file.
1283  */
1284  if (target_monitor_was_interrupted(&siginfo)) {
1285  if (needtodie) {
1286  rc = 0;
1287  goto exit;
1288  }
1289  else if (siginfo.si_signo == SIGUSR1
1290  || siginfo.si_signo == SIGUSR2
1291  || siginfo.si_signo == SIGHUP) {
1293  }
1294 
1296 
1297  v_g_list_foreach(targets,t1,target) {
1298  target_resume(target);
1299  }
1300  }
1301  /* Did we experience an error in select() or in evloop? */
1302  else if (rc < 0) {
1303  fprintf(stderr,"error in target_monitor_evloop (%d): %s; aborting!\n",
1304  rc,strerror(errno));
1305  rc = -3;
1306  goto exit;
1307  }
1308  /* Did we experience a significant event on a target? */
1309  else if (rc == 0 && evloop_maxsize(evloop) < 0) {
1310  break;
1311  }
1312  else if (rc == 0) {
1313  tid = target_gettid(t);
1314  tname = target_name(t);
1315 
1316  if (tstat == TSTATUS_ERROR) {
1317  fprintf(stderr,
1318  "Error handling target '%s'; closing and finalizing!\n",
1319  tname);
1320 
1321  target_close(t);
1322  target_finalize(t);
1323  targets = g_list_remove(targets,t);
1324  }
1325  else if (tstat == TSTATUS_DONE) {
1326  fprintf(stderr,
1327  "Target '%s' finished; finalizing!\n",
1328  tname);
1329 
1330  target_close(t);
1331  target_finalize(t);
1332  targets = g_list_remove(targets,t);
1333  }
1334  else if (tstat == TSTATUS_EXITING) {
1335  fprintf(stderr,"Target '%s' exiting...\n",tname);
1336  }
1337  else if (tstat == TSTATUS_INTERRUPTED) {
1338  fprintf(stderr,"Target '%s' interrupted, resuming...\n",tname);
1339  if (target_resume(t)) {
1340  fprintf(stderr,"Could not resume target %s tid %"PRIiTID"\n",
1341  tname,tid);
1342 
1343  target_close(t);
1344  target_finalize(t);
1345  targets = g_list_remove(targets,t);
1346  }
1347  }
1348  else {
1349  fprintf(stderr,
1350  "Target '%s' tid %d received unexpected status '%s'"
1351  " at 0x%"PRIxADDR"; attempting to continue!\n",
1352  tname,tid,TSTATUS(tstat),target_read_reg(t,tid,CREG_IP));
1353  if (target_resume(t)) {
1354  fprintf(stderr,"Could not resume target %s tid %"PRIiTID"\n",
1355  tname,tid);
1356 
1357  target_close(t);
1358  target_finalize(t);
1359  targets = g_list_remove(targets,t);
1360  }
1361  }
1362  }
1363  }
1364 
1365  rc = 0;
1366 
1367  exit:
1368  fflush(stderr);
1369  fflush(stdout);
1370  cleanup_probes();
1372  if (rc < 0)
1373  exit(rc);
1374  else
1375  exit(needtodie_exitcode);
1376 }
1377 
1378 void spf_action_free(struct spf_action *spfa) {
1379  if (spfa->atype == SPF_ACTION_REPORT) {
1380  if (spfa->report.tn)
1381  free(spfa->report.tn);
1382  if (spfa->report.rv)
1383  free(spfa->report.rv);
1384  if (spfa->report.msg)
1385  free(spfa->report.msg);
1386  }
1387  else if (spfa->atype == SPF_ACTION_ENABLE) {
1388  if (spfa->enable.id)
1389  free(spfa->enable.id);
1390  }
1391  else if (spfa->atype == SPF_ACTION_DISABLE) {
1392  if (spfa->disable.id)
1393  free(spfa->disable.id);
1394  }
1395  else if (spfa->atype == SPF_ACTION_REMOVE) {
1396  if (spfa->remove.id)
1397  free(spfa->remove.id);
1398  }
1399 
1400  free(spfa);
1401 }
1402 
1403 void spf_filter_free(struct spf_filter *spff) {
1404  GSList *gsltmp;
1405  struct spf_action *spfa;
1406 
1407  if (spff->id)
1408  free(spff->id);
1409  if (spff->symbol)
1410  free(spff->symbol);
1411  if (spff->bsymbol)
1412  bsymbol_release(spff->bsymbol);
1413  if (spff->pf)
1414  target_nv_filter_free(spff->pf);
1415  if (spff->actions) {
1416  v_g_slist_foreach(spff->actions,gsltmp,spfa) {
1417  spf_action_free(spfa);
1418  }
1419  g_slist_free(spff->actions);
1420  }
1421 
1422  free(spff);
1423 }
1424 
1425 void spf_config_free(struct spf_config *config) {
1426  GSList *gsltmp;
1427  struct spf_filter *spff;
1428 
1429  v_g_slist_foreach(config->spf_filter_list,gsltmp,spff) {
1430  spf_filter_free(spff);
1431  }
1432  g_slist_free(config->spf_filter_list);
1433 }
1434 
1435 /*
1436  * Language is like this. Single lines of probe filters/actions.
1437  *
1438  * [ see README.spf.txt ]
1439  *
1440  * Reports interpreted by the XML server like this:
1441  *
1442  * "RESULT:: (%c:%d) %ms (%d) %ms \"%m[^\"]\" (%m[^)]) ::RESULT\n",
1443  * &rt,&id,&name,&type,&result_value,&msg,&value_str);
1444  *
1445  * rt=(i|f) id=<unique_int> typename typeid result_value "msg" (<meta_kv_pairs>)
1446  *
1447  * We often use result_value as a msg subtype field within typename/typeid.
1448  */
1449 
1450 char *_get_next_non_enc_esc(char *s,int c) {
1451  int wasesc = 0;
1452  int isesc = 0;
1453  int isenc = 0;
1454  int encchar;
1455 
1456  while (*s != '\0') {
1457  wasesc = isesc;
1458  isesc = 0;
1459  if (isenc) {
1460  if (*s == '\\') {
1461  if (!wasesc)
1462  isesc = 1;
1463  }
1464  else if (*s == encchar && !wasesc) {
1465  encchar = '\0';
1466  isenc = 0;
1467  }
1468  }
1469  else if (*s == c) {
1470  if (!wasesc)
1471  break;
1472  }
1473  else if (*s == '\\') {
1474  if (!wasesc)
1475  isesc = 1;
1476  }
1477 
1478  ++s;
1479  }
1480 
1481  if (*s == c)
1482  return s;
1483  else
1484  return NULL;
1485 }
1486 
1488  struct spf_config *newconfig;
1489 
1490  newconfig = load_config_file(opts.config_file);
1491  if (!newconfig) {
1492  if (opts.config_file_fatal) {
1493  verror("could not reread config file %s!\n",opts.config_file);
1494  cleanup_probes();
1496  exit(-1);
1497  }
1498  else {
1499  vwarn("could not reread config file %s; leaving"
1500  " existing configuration in place!\n",opts.config_file);
1501  }
1502  }
1503  else {
1504  apply_config_file(newconfig);
1505  //spf_config_free(config);
1506  config = newconfig;
1507  newconfig = NULL;
1508  }
1509 }
1510 
1511 /*
1512  * Applies the config file.
1513  *
1514  * The easiest thing to do is remove all the filter probes; then see
1515  * which symbol probes we need to add/remove; then re-add all the
1516  * filter probes.
1517  *
1518  * What happens if we get called while one of our filter probes is
1519  * running its handler (or the list the probe is on is getting
1520  * iterated)?
1521  *
1522  * Sigh... we're going to have to add this aren't we. probe_free() will
1523  * have to schedule a free if the probe is in use...
1524  */
1525 int apply_config_file(struct spf_config *config) {
1526  GSList *gsltmp;
1527  struct spf_filter *spff;
1528  struct bsymbol *bsymbol = NULL;
1529  GHashTable *needed = NULL;
1530  GHashTableIter iter;
1531  gpointer kp,vp;
1532  struct probe *probe,*sprobe,*fprobe;
1533  char namebuf[128];
1534  int i;
1535  struct target_os_syscall *syscall;
1536  GList *t1;
1537  struct target *target;
1538 
1539  /* First, destroy all the filter probes. */
1540  g_hash_table_iter_init(&iter,fprobes);
1541  while (g_hash_table_iter_next(&iter,&kp,&vp)) {
1542  probe = (struct probe *)vp;
1543  probe_free(probe,0);
1544  g_hash_table_iter_remove(&iter);
1545  }
1546 
1547  /* Second, build symbol probes for all the probes in the config. */
1548  needed = g_hash_table_new(g_str_hash,g_str_equal);
1549  v_g_slist_foreach(config->spf_filter_list,gsltmp,spff) {
1550  g_hash_table_insert(needed,spff->symbol,NULL);
1551 
1552  if (g_hash_table_lookup(sprobes,spff->symbol))
1553  continue;
1554 
1555  /* Create it. */
1556  bsymbol = NULL;
1557  v_g_list_foreach(targets,t1,target) {
1558  bsymbol = target_lookup_sym(target,spff->symbol,NULL,spff->srcfile,
1560  if (bsymbol)
1561  break;
1562  }
1563 
1564  if (!bsymbol)
1565  bsymbol = target_lookup_sym(target,spff->symbol,NULL,spff->srcfile,
1567 
1568  if (!bsymbol) {
1569  if (opts.config_file_fatal) {
1570  verror("could not lookup symbol %s; aborting!\n",
1571  spff->symbol);
1572  cleanup_probes();
1574  exit(-3);
1575  }
1576  else {
1577  vwarn("could not lookup symbol %s; skipping filter!\n",
1578  spff->symbol);
1579  continue;
1580  }
1581  }
1582 
1583  sprobe = NULL;
1585  v_g_list_foreach(targets,t1,target) {
1586  if (target->personality != TARGET_PERSONALITY_OS)
1587  continue;
1588 
1589  syscall = target_os_syscall_lookup_name(target,spff->symbol);
1590  if (syscall) {
1591  sprobe = target_os_syscall_probe(target,TID_GLOBAL,syscall,
1594  NULL);
1595  if (!sprobe) {
1596  if (opts.config_file_fatal) {
1597  verror("could not place syscall value probe on %s;"
1598  " aborting!\n",
1599  spff->symbol);
1600  cleanup_probes();
1602  exit(-3);
1603  }
1604  else {
1605  vwarn("could not place syscall value probe on %s;"
1606  " skipping filter!\n",
1607  spff->symbol);
1608  continue;
1609  }
1610  }
1611  }
1612  }
1613  }
1614 
1615  if (!sprobe) {
1616  sprobe = probe_value_symbol(bsymbol->region->space->target,
1617  TID_GLOBAL,bsymbol,
1620  if (!sprobe) {
1621  if (opts.config_file_fatal) {
1622  verror("could not place value probe on %s; aborting!\n",
1623  spff->symbol);
1624  cleanup_probes();
1626  exit(-3);
1627  }
1628  else {
1629  vwarn("could not place value probe on %s; skipping filter!\n",
1630  spff->symbol);
1631  continue;
1632  }
1633  }
1634  }
1635 
1636  g_hash_table_insert(sprobes,spff->symbol,sprobe);
1637  }
1638 
1639  /* Third, any sprobe that is *NOT* in needed should be removed. */
1640  g_hash_table_iter_init(&iter,sprobes);
1641  while (g_hash_table_iter_next(&iter,&kp,&vp)) {
1642  if (g_hash_table_lookup_extended(needed,kp,NULL,NULL) == FALSE) {
1643  probe_free((struct probe *)vp,0);
1644  g_hash_table_iter_remove(&iter);
1645  }
1646  }
1647  g_hash_table_destroy(needed);
1648  needed = NULL;
1649 
1650  /* Finally, add all the filter probes. */
1651  v_g_slist_foreach(config->spf_filter_list,gsltmp,spff) {
1652  /* Again, if we failed for any reason to get the symbol, skip here. */
1653  sprobe = (struct probe *)g_hash_table_lookup(sprobes,spff->symbol);
1654  if (!sprobe)
1655  continue;
1656  if (!spff->id) {
1657  snprintf(namebuf,sizeof(namebuf),"filter_%s_%d",spff->symbol,i);
1658  spff->id = strdup(namebuf);
1659  }
1660  if (spff->when == WHEN_PRE)
1661  fprobe = probe_create_filtered(sprobe->target,TID_GLOBAL,NULL,spff->id,
1662  pre_handler,spff->pf,null_handler,NULL,
1663  spff->ttf,spff,0,1);
1664  else
1665  fprobe = probe_create_filtered(sprobe->target,TID_GLOBAL,NULL,spff->id,
1666  null_handler,NULL,post_handler,spff->pf,
1667  spff->ttf,spff,0,1);
1668  probe_register_source(fprobe,sprobe);
1669 
1670  if (spff->disable)
1671  probe_disable(fprobe);
1672 
1673  g_hash_table_insert(fprobes,spff->id,fprobe);
1674  }
1675 
1676  return 0;
1677 }
1678 
1679 /*
1680  * (Re)reads the configuration file.
1681  */
1682 struct spf_config *load_config_file(char *file) {
1683  char *buf;
1684  char *bufptr;
1685  char *tbuf;
1686  int bufsiz = 128;
1687  int rc = 0;
1688  FILE *ffile;
1689  struct spf_filter *spff = NULL;
1690  struct spf_action *spfa = NULL;
1691  char *saveptr;
1692  char *token = NULL, *token2 = NULL;
1693  char *tptr;
1694  long int numval;
1695  struct spf_config *retval = NULL;
1696  int spff_count = 0;
1697  int lineno = 0;
1698  char *tmp;
1699 
1700  if (strcmp(file,"-") == 0)
1701  ffile = stdin;
1702  else {
1703  ffile = fopen(file,"r");
1704  if (!ffile) {
1705  verror("could not fopen config file %s: %s\n",file,strerror(errno));
1706  return NULL;
1707  }
1708  }
1709 
1710  retval = calloc(1,sizeof(*retval));
1711 
1712  /* Read directives line by line. */
1713  buf = malloc(bufsiz);
1714  while (1) {
1715  rc = 0;
1716  while (1) {
1717  errno = 0;
1718  tbuf = fgets(buf + rc,bufsiz - rc,ffile);
1719  if (tbuf && (rc += strlen(buf + rc)) == (bufsiz - 1)
1720  && buf[bufsiz - 2] != '\n') {
1721  /* We filled up the buf; malloc more and keep going. */
1722  tbuf = malloc(bufsiz + 128);
1723  memcpy(tbuf,buf,bufsiz);
1724  free(buf);
1725  buf = tbuf;
1726  bufsiz += 128;
1727  }
1728  else if (tbuf && rc < bufsiz) {
1729  /* We have our line. */
1730  break;
1731  }
1732  else if (errno) {
1733  verror("fgets: %s (aborting filter file read)\n",
1734  strerror(errno));
1735  goto errout;
1736  }
1737  else {
1738  /* EOF. */
1739  free(buf);
1740  buf = NULL;
1741  break;
1742  }
1743  }
1744 
1745  if (!buf)
1746  break;
1747 
1748  ++lineno;
1749  vdebug(2,LA_USER,LF_U_CFG,"read line %d: '%s'\n",lineno,buf);
1750 
1751  if (*buf == '#')
1752  continue;
1753 
1754  if (buf[strlen(buf) - 1] == '\n') {
1755  if (*buf == '\n')
1756  continue;
1757  buf[strlen(buf) - 1] = '\0';
1758  }
1759 
1760  /*
1761  * ProbeFilter.
1762  */
1763  if (strncmp(buf,"ProbeFilter",strlen("ProbeFilter")) == 0) {
1764  bufptr = buf + strlen("ProbeFilter");
1765  while (isspace(*bufptr)) ++bufptr;
1766 
1767  spff = (struct spf_filter *)calloc(1,sizeof(*spff));
1768  /* Default. */
1769  spff->when = WHEN_PRE;
1770 
1771  /*
1772  * Parse the line. We can't use strtok to split it up,
1773  * because there are strings and regexps, and we don't want
1774  * to place any restrictions on them. So we just manually
1775  * lex it... forgotten too much flex yystuff to do it fast.
1776  */
1777 
1778  /* symbol name */
1779  token = bufptr;
1780  while (!isspace(*bufptr)) ++bufptr;
1781  *bufptr = '\0';
1782  spff->symbol = strdup(token);
1783  if ((tmp = index(spff->symbol,':'))) {
1784  spff->srcfile = spff->symbol;
1785  *tmp = '\0';
1786  spff->symbol = strdup(tmp+1);
1787  }
1788  ++bufptr;
1789 
1790  /* These are all optional; take them in any order. */
1791  while (*bufptr != '\0') {
1792  while (isspace(*bufptr)) ++bufptr;
1793  if (*bufptr == '\0')
1794  goto err;
1795 
1796  token = bufptr;
1797  while (isalnum(*bufptr) || *bufptr == '_') ++bufptr;
1798  if (*bufptr == '(') {
1799  *bufptr = '\0';
1800  ++bufptr;
1801  }
1802  else {
1803  *bufptr = '\0';
1804  ++bufptr;
1805  while (isspace(*bufptr)) ++bufptr;
1806  if (*bufptr != '(')
1807  goto err;
1808  ++bufptr;
1809  }
1810 
1811  if (strcmp(token,"id") == 0) {
1812  token = bufptr;
1813  while (isalnum(*bufptr) || *bufptr == '_') ++bufptr;
1814  if (*bufptr != ')')
1815  goto err;
1816  *bufptr = '\0';
1817  ++bufptr;
1818  if (spff->id)
1819  goto err;
1820  else
1821  spff->id = strdup(token);
1822  }
1823  else if (strcmp(token,"when") == 0) {
1824  if (strncmp(bufptr,"pre",strlen("pre")) == 0) {
1825  spff->when = WHEN_PRE;
1826  bufptr += strlen("pre");
1827  }
1828  else if (strncmp(bufptr,"post",strlen("post")) == 0) {
1829  spff->when = WHEN_POST;
1830  bufptr += strlen("post");
1831  }
1832  else
1833  goto err;
1834  if (*bufptr != ')')
1835  goto err;
1836  ++bufptr;
1837  }
1838  else if (strcmp(token,"disable") == 0) {
1839  if (*bufptr != ')')
1840  goto err;
1841  ++bufptr;
1842 
1843  spff->disable = 1;
1844  }
1845  else if (strcmp(token,"vfilter") == 0) {
1846  if (spff->pf)
1847  goto err;
1848  token = bufptr;
1849  /* Find the enclosing ')' */
1850  int isescaped = 0;
1851  char *nextbufptr = NULL;
1852  while (*bufptr != '\0') {
1853  if (*bufptr == '\\') {
1854  if (!isescaped)
1855  isescaped = 1;
1856  else
1857  isescaped = 0;
1858  }
1859  else if (*bufptr == ')' && !isescaped) {
1860  nextbufptr = bufptr + 1;
1861  *bufptr = '\0';
1862  break;
1863  }
1864  ++bufptr;
1865  }
1866  if (!nextbufptr)
1867  goto err;
1868  spff->pf = target_nv_filter_parse(token);
1869  if (!spff->pf)
1870  goto err;
1871  bufptr = nextbufptr;
1872  }
1873  else if (strcmp(token,"tfilter") == 0) {
1874  if (spff->ttf)
1875  goto err;
1876  token = bufptr;
1877  /* Find the enclosing ')' */
1878  int isescaped = 0;
1879  char *nextbufptr = NULL;
1880  while (*bufptr != '\0') {
1881  if (*bufptr == '\\') {
1882  if (!isescaped)
1883  isescaped = 1;
1884  else
1885  isescaped = 0;
1886  }
1887  else if (*bufptr == ')' && !isescaped) {
1888  nextbufptr = bufptr + 1;
1889  *bufptr = '\0';
1890  break;
1891  }
1892  ++bufptr;
1893  }
1894  if (!nextbufptr)
1895  goto err;
1896  spff->ttf = target_nv_filter_parse(token);
1897  if (!spff->ttf)
1898  goto err;
1899  bufptr = nextbufptr;
1900  }
1901  else if (strcmp(token,"abort") == 0) {
1902  token = bufptr;
1903  while (*bufptr == '-' || isdigit(*bufptr)) ++bufptr;
1904  if (*bufptr != ')')
1905  goto err;
1906  *bufptr = '\0';
1907  ++bufptr;
1908  errno = 0;
1909  numval = strtol(token,NULL,0);
1910  if (errno)
1911  goto err;
1912 
1913  spfa = calloc(1,sizeof(*spfa));
1914  spfa->atype = SPF_ACTION_ABORT;
1915  spfa->abort.retval = numval;
1916 
1917  spff->actions = g_slist_append(spff->actions,spfa);
1918  spfa = NULL;
1919  }
1920  else if (strcmp(token,"print") == 0) {
1921  spfa = calloc(1,sizeof(*spfa));
1922  spfa->atype = SPF_ACTION_PRINT;
1923 
1924  if (*bufptr == ')') {
1925  ++bufptr;
1926  }
1927  else {
1928  /*
1929  * XXX: use strtok here ignore the possibility that
1930  * the msg field has a comma in it. Time is not on
1931  * my side...
1932  */
1933  char *nextbufptr = NULL;
1934  nextbufptr = _get_next_non_enc_esc(bufptr,')');
1935  if (!nextbufptr)
1936  goto err;
1937  *nextbufptr = '\0';
1938  ++nextbufptr;
1939  token = NULL;
1940  token2 = NULL;
1941  saveptr = NULL;
1942  while ((token = strtok_r((!token) ? bufptr : NULL,",",
1943  &saveptr))) {
1944  tptr = token;
1945  while (*tptr != '\0') {
1946  if (*tptr == '=') {
1947  *tptr = '\0';
1948  token2 = ++tptr;
1949  break;
1950  }
1951  ++tptr;
1952  }
1953  if (!token2)
1954  goto err;
1955 
1956  if (strcmp(token,"ttctx") == 0) {
1957  if (strcmp(token2,"none") == 0)
1958  spfa->print.ttctx = 0;
1959  else if (strcmp(token2,"self") == 0)
1960  spfa->print.ttctx = 1;
1961  else if (strcmp(token2,"hier") == 0)
1962  spfa->print.ttctx = 2;
1963  else if (strcmp(token2,"all") == 0)
1964  spfa->print.ttctx = 3;
1965  else
1966  goto err;
1967  }
1968  else if (strcmp(token,"ttdetail") == 0) {
1969  spfa->print.ttdetail = atoi(token2);
1970  }
1971  else
1972  goto err;
1973  }
1974  bufptr = nextbufptr;
1975  }
1976 
1977  spff->actions = g_slist_append(spff->actions,spfa);
1978  spfa = NULL;
1979  }
1980  else if (strcmp(token,"report") == 0) {
1981  spfa = calloc(1,sizeof(*spfa));
1982  spfa->atype = SPF_ACTION_REPORT;
1983 
1984  /* Set some defaults. */
1985  spfa->report.rt = 'i';
1986  spfa->report.overlay_levels = 0;
1987  spfa->report.overlay_debuginfo_prefix = NULL;
1988 
1989  /*
1990  * XXX: use strtok here ignore the possibility that
1991  * the msg field has a comma in it. Time is not on
1992  * my side...
1993  */
1994  char *nextbufptr = NULL;
1995  nextbufptr = _get_next_non_enc_esc(bufptr,')');
1996  if (!nextbufptr)
1997  goto err;
1998  *nextbufptr = '\0';
1999  ++nextbufptr;
2000  token = NULL;
2001  token2 = NULL;
2002  saveptr = NULL;
2003  while ((token = strtok_r((!token) ? bufptr : NULL,",",
2004  &saveptr))) {
2005  tptr = token;
2006  while (*tptr != '\0') {
2007  if (*tptr == '=') {
2008  *tptr = '\0';
2009  token2 = ++tptr;
2010  break;
2011  }
2012  ++tptr;
2013  }
2014  if (!token2)
2015  goto err;
2016 
2017  if (strcmp(token,"rt") == 0) {
2018  if (*token2 == 'f')
2019  spfa->report.rt = *token2;
2020  else if (*token2 == 'i')
2021  spfa->report.rt = *token2;
2022  else
2023  goto err;
2024  }
2025  else if (strcmp(token,"tn") == 0) {
2026  spfa->report.tn = strdup(token2);
2027  }
2028  else if (strcmp(token,"tid") == 0) {
2029  errno = 0;
2030  spfa->report.tid = strtol(token2,NULL,0);
2031  if (errno)
2032  goto err;
2033  }
2034  else if (strcmp(token,"rv") == 0) {
2035  spfa->report.rv = strdup(token2);
2036  }
2037  else if (strcmp(token,"msg") == 0) {
2038  if (*token2 != '"') {
2039  spfa->report.msg = malloc(2+1+strlen(token2));
2040  snprintf(spfa->report.msg,2+1+strlen(token2),
2041  "\"%s\"",token2);
2042  }
2043  else
2044  spfa->report.msg = strdup(token2);
2045  }
2046  else if (strcmp(token,"ttctx") == 0) {
2047  if (strcmp(token2,"none") == 0)
2048  spfa->report.ttctx = 0;
2049  else if (strcmp(token2,"self") == 0)
2050  spfa->report.ttctx = 1;
2051  else if (strcmp(token2,"hier") == 0)
2052  spfa->report.ttctx = 2;
2053  else if (strcmp(token2,"all") == 0)
2054  spfa->report.ttctx = 3;
2055  else
2056  goto err;
2057  }
2058  else if (strcmp(token,"ttdetail") == 0) {
2059  spfa->report.ttdetail = atoi(token2);
2060  }
2061  else if (strcmp(token,"bt") == 0) {
2062  spfa->report.bt = atoi(token2);
2063  }
2064  else if (strcmp(token,"overlay_levels") == 0) {
2065  spfa->report.overlay_levels = atoi(token2);
2066  }
2067  else if (strcmp(token,"overlay_debuginfo_root_prefix") == 0) {
2068  spfa->report.overlay_debuginfo_prefix =
2069  strdup(token2);
2070  }
2071  else
2072  goto err;
2073  }
2074  bufptr = nextbufptr;
2075 
2076  spff->actions = g_slist_append(spff->actions,spfa);
2077  spfa = NULL;
2078  }
2079  else if (strcmp(token,"exit") == 0) {
2080  token = bufptr;
2081  while (*bufptr == '-' || isdigit(*bufptr)) ++bufptr;
2082  if (*bufptr != ')')
2083  goto err;
2084  *bufptr = '\0';
2085  ++bufptr;
2086  errno = 0;
2087  numval = strtol(token,NULL,0);
2088  if (errno)
2089  goto err;
2090 
2091  spfa = calloc(1,sizeof(*spfa));
2092  spfa->atype = SPF_ACTION_EXIT;
2093  spfa->exit.retval = numval;
2094 
2095  spff->actions = g_slist_append(spff->actions,spfa);
2096  spfa = NULL;
2097  }
2098  else if (strcmp(token,"enable") == 0) {
2099  token = bufptr;
2100  while (isalnum(*bufptr) || *bufptr == '_') ++bufptr;
2101  if (*bufptr != ')')
2102  goto err;
2103  *bufptr = '\0';
2104  ++bufptr;
2105  spfa = calloc(1,sizeof(*spfa));
2106  spfa->atype = SPF_ACTION_ENABLE;
2107  spfa->enable.id = strdup(token);
2108 
2109  spff->actions = g_slist_append(spff->actions,spfa);
2110  spfa = NULL;
2111  }
2112  else if (strcmp(token,"disable") == 0) {
2113  token = bufptr;
2114  while (isalnum(*bufptr) || *bufptr == '_') ++bufptr;
2115  if (*bufptr != ')')
2116  goto err;
2117  *bufptr = '\0';
2118  ++bufptr;
2119  spfa = calloc(1,sizeof(*spfa));
2120  spfa->atype = SPF_ACTION_DISABLE;
2121  spfa->disable.id = strdup(token);
2122 
2123  spff->actions = g_slist_append(spff->actions,spfa);
2124  spfa = NULL;
2125  }
2126  else if (strcmp(token,"remove") == 0) {
2127  token = bufptr;
2128  while (isalnum(*bufptr) || *bufptr == '_') ++bufptr;
2129  if (*bufptr != ')')
2130  goto err;
2131  *bufptr = '\0';
2132  ++bufptr;
2133  spfa = calloc(1,sizeof(*spfa));
2134  spfa->atype = SPF_ACTION_REMOVE;
2135  spfa->remove.id = strdup(token);
2136 
2137  spff->actions = g_slist_append(spff->actions,spfa);
2138  spfa = NULL;
2139  }
2140  else if (strcmp(token,"bt") == 0) {
2141  spfa = calloc(1,sizeof(*spfa));
2142  spfa->atype = SPF_ACTION_BT;
2143 
2144  /* Set some defaults. */
2145  spfa->bt.tid = -1;
2146  spfa->bt.thid = NULL;
2147  spfa->bt.overlay_levels = 0;
2148  spfa->bt.overlay_debuginfo_prefix = NULL;
2149 
2150  char *nextbufptr = NULL;
2151  nextbufptr = _get_next_non_enc_esc(bufptr,')');
2152  if (!nextbufptr)
2153  goto err;
2154  *nextbufptr = '\0';
2155  ++nextbufptr;
2156  token = NULL;
2157  token2 = NULL;
2158  saveptr = NULL;
2159 
2160  int lpc = 0;
2161  while ((token = strtok_r((!token) ? bufptr : NULL,",",
2162  &saveptr))) {
2163  if (lpc == 0)
2164  spfa->bt.tid = atoi(token);
2165  else if (lpc == 1)
2166  spfa->bt.thid = strdup(token);
2167  else if (lpc == 2)
2168  spfa->bt.overlay_levels = atoi(token);
2169  else if (lpc == 3)
2170  spfa->bt.overlay_debuginfo_prefix = strdup(token);
2171  else
2172  goto err;
2173 
2174  ++lpc;
2175  }
2176  bufptr = nextbufptr;
2177 
2178  spff->actions = g_slist_append(spff->actions,spfa);
2179  spfa = NULL;
2180  }
2181  else if (strcmp(token,"signal") == 0) {
2182  spfa = calloc(1,sizeof(*spfa));
2183  spfa->atype = SPF_ACTION_SIGNAL;
2184 
2185  /* Set some defaults. */
2186  spfa->signal.tid = -1;
2187  spfa->signal.thid = NULL;
2188 
2189  char *nextbufptr = NULL;
2190  nextbufptr = _get_next_non_enc_esc(bufptr,')');
2191  if (!nextbufptr)
2192  goto err;
2193  *nextbufptr = '\0';
2194  ++nextbufptr;
2195  token = NULL;
2196  token2 = NULL;
2197  saveptr = NULL;
2198 
2199  int lpc = 0;
2200  while ((token = strtok_r((!token) ? bufptr : NULL,",",
2201  &saveptr))) {
2202  if (lpc == 0)
2203  spfa->signal.tid = atoi(token);
2204  else if (lpc == 1)
2205  spfa->signal.thid = strdup(token);
2206  else if (lpc == 2)
2207  spfa->signal.sigdesc = strdup(token);
2208  else
2209  goto err;
2210 
2211  ++lpc;
2212  }
2213  bufptr = nextbufptr;
2214 
2215  spff->actions = g_slist_append(spff->actions,spfa);
2216  spfa = NULL;
2217  }
2218  else
2219  goto err;
2220  }
2221 
2222  retval->spf_filter_list =
2223  g_slist_append(retval->spf_filter_list,spff);
2224  spff = NULL;
2225  ++spff_count;
2226  }
2227  else {
2228  /*
2229  * Invalid rule
2230  */
2231  fprintf(stderr,"ERROR: unknown config directive line %d:\n",lineno);
2232  fprintf(stderr,"%s\n", buf);
2233  goto errout;
2234  }
2235  }
2236 
2237  fclose(ffile);
2238 
2239  if (buf)
2240  free(buf);
2241 
2242  vdebug(2,LA_USER,LF_U_CFG,"configfile: %d probefilters.\n",spff_count);
2243 
2244  return retval;
2245 
2246  err:
2247  verror("parse error at line %d col %d: '%.48s ...'\n",
2248  lineno,(int)(bufptr - buf),bufptr);
2249 
2250  errout:
2251  fclose(ffile);
2252 
2253  if (spfa)
2254  spf_action_free(spfa);
2255  if (spff)
2256  spf_filter_free(spff);
2257  if (retval)
2258  spf_config_free(retval);
2259 
2260  if (buf)
2261  free(buf);
2262 
2263  return NULL;
2264 }
struct target * target_instantiate_overlay(struct target *target, tid_t tid, struct target_spec *spec)
Definition: target_api.c:757
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
void print_thread_context(FILE *stream, struct target *target, tid_t tid, int ttctx, int ttdetail, int bt, int overlay_levels, char *overlay_debuginfo_prefix, char *sep, char *kvsep, char *tprefix, char *tsep)
Definition: spf.c:219
struct action * action_return(REGVAL retval)
Definition: probe.c:4457
result_t pre_handler(struct probe *probe, tid_t tid, void *data, struct probe *trigger, struct probe *base)
Definition: spf.c:903
int bt
Definition: spf.c:72
void spf_backtrace(struct target *t, tid_t ctid, char *tiddesc, int overlay_levels, char *overlay_debuginfo_prefix)
Definition: spf.c:354
struct probe * probe_value_symbol(struct target *target, tid_t tid, struct bsymbol *bsymbol, probe_handler_t pre_handler, probe_handler_t post_handler, void *handler_data)
Definition: probe_value.c:660
#define __TARGET_OVERLAY
Definition: spf.c:924
int probe_unregister(struct probe *probe, int force)
Definition: probe.c:1137
void reload_config_file(void)
Definition: spf.c:1487
void target_monitor_schedule_global_interrupt(void)
Definition: target.c:321
int argc
Definition: spf.c:143
char * id
Definition: spf.c:113
int value_snprintf(struct value *value, char *buf, int buflen)
Definition: value.c:639
int ttctx
Definition: spf.c:70
int use_os_syscall_probes
Definition: spf.c:147
char * rv
Definition: spf.c:68
int32_t tid_t
Definition: common.h:36
target_personality_t personality
Definition: target_api.h:2515
void * target_argp_driver_state(struct argp_state *state)
Definition: target.c:716
struct target_nv_filter * ttf
Definition: spf.c:128
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 spf_config * load_config_file(char *file)
Definition: spf.c:1682
Definition: probe.h:392
char * name
Definition: probe.h:314
sigset_t interrupt
Definition: spf.c:211
static uint64_t unsigned int i
struct bsymbol * target_lookup_sym(struct target *target, const char *name, const char *delim, char *srcfile, symbol_type_flag_t ftype)
Definition: target.c:2199
int target_monitor_evloop(struct evloop *evloop, struct timeval *timeout, struct target **target, target_status_t *status)
Definition: target_api.c:880
void target_init(void)
Definition: target.c:69
Definition: arch.h:74
REFCNT action_release(struct action *action)
Definition: probe.c:4576
result_t handler(int when, struct probe *probe, tid_t tid, void *data, struct probe *trigger, struct probe *base)
Definition: spf.c:561
#define v_g_slist_foreach(gslhead, gslcur, elm)
Definition: glib_wrapper.h:60
int target_resume(struct target *target)
Definition: target_api.c:1012
struct overlay_spec ** ospecs
Definition: spf.c:149
struct bsymbol * bsymbol
Definition: spf.c:117
#define v_g_list_foreach(glhead, glcur, elm)
Definition: glib_wrapper.h:34
result_t null_handler(struct probe *probe, tid_t tid, void *data, struct probe *trigger, struct probe *base)
Definition: spf.c:918
char * msg
Definition: spf.c:69
int target_pause(struct target *target)
Definition: target_api.c:1027
char * thid
Definition: spf.c:97
#define PROBE_VALUE_NAME_RETURN
Definition: probe_api.h:159
tid_t target_gettid(struct target *target)
Definition: target_api.c:1918
struct argp_option spf_argp_opts[]
Definition: spf.c:928
struct probe * probe_create_filtered(struct target *target, tid_t tid, struct probe_ops *pops, const char *name, probe_handler_t pre_handler, struct target_nv_filter *pre_filter, probe_handler_t post_handler, struct target_nv_filter *post_filter, struct target_nv_filter *thread_filter, void *handler_data, int autofree, int tracked)
Definition: probe_filter.c:95
GHashTable * probe_value_get_table(struct probe *probe, tid_t tid)
Definition: probe_value.c:618
struct target * target
Definition: target.h:895
result_t probe_do_sink_post_handlers(struct probe *probe, tid_t tid, void *handler_data, struct probe *trigger, struct probe *base)
Definition: probe.c:109
GHashTable * fprobes
Definition: spf.c:160
struct spf_action::@30::@38 remove
struct target_os_syscall * target_os_syscall_lookup_name(struct target *target, char *name)
Definition: target_os.c:437
int config_file_fatal
Definition: spf.c:146
int target_close(struct target *target)
Definition: target_api.c:1511
struct spf_action::@30::@32 report
struct list_head probe
Definition: probe.h:379
#define verror(format,...)
Definition: log.h:30
result_t probe_do_sink_pre_handlers(struct probe *probe, tid_t tid, void *handler_data, struct probe *trigger, struct probe *base)
Definition: probe.c:48
GHashTable * sprobes
Definition: spf.c:159
int target_install_custom_sighandlers(sigset_t *ignored, sigset_t *interrupt, sigset_t *exit, void(*sighandler)(int signo, siginfo_t *siginfo, void *x))
Definition: target.c:270
int tid
Definition: spf.c:67
GSList * actions
Definition: spf.c:129
char * _get_next_non_enc_esc(char *s, int c)
Definition: spf.c:1450
Definition: evloop.h:66
void target_fini(void)
Definition: target.c:91
char * config_file
Definition: spf.c:145
#define LF_U_CFG
Definition: spf.c:42
struct spf_action::@30::@33 print
#define vwarn(format,...)
Definition: log.h:33
#define LF_U_PROBE
Definition: spf.c:43
void free(void *ptr)
Definition: debugserver.c:207
REGVAL target_read_reg(struct target *target, tid_t tid, REG reg)
Definition: target_api.c:1132
void spf_filter_free(struct spf_filter *spff)
Definition: spf.c:1403
struct spf_argp_state opts
Definition: spf.c:157
struct spf_action::@30::@36 enable
tid_t tid
Definition: probe.h:344
struct probe * probe_register_source(struct probe *sink, struct probe *src)
Definition: probe.c:1593
error_t spf_argp_parse_opt(int key, char *arg, struct argp_state *state)
Definition: spf.c:938
struct target_nv_filter * pf
Definition: spf.c:124
#define array_list_foreach(alist, lpc, placeholder)
Definition: alist.h:371
void target_monitor_clear_global_interrupt(void)
Definition: target.c:235
void spf_config_free(struct spf_config *config)
Definition: spf.c:1425
void target_default_cleanup()
Definition: target.c:128
struct spf_action::@30::@35 exit
REFCNT bsymbol_release(struct bsymbol *bsymbol)
Definition: symbol.c:90
int target_argp_driver_parse(struct argp *driver_parser, void *driver_state, int argc, char **argv, target_type_t target_types, int filter_quoted, struct target_spec **primary_target_spec, GList **base_target_specs, GList **overlay_target_specs)
Definition: target.c:913
int target_monitor_was_interrupted(siginfo_t *last_siginfo)
Definition: target.c:226
struct array_list * target_list_tids(struct target *target)
Definition: target_api.c:1210
int target_os_syscall_table_load(struct target *target)
Definition: target_os.c:415
int result_counter
Definition: spf.c:165
struct probe * target_os_syscall_probe(struct target *target, tid_t tid, struct target_os_syscall *syscall, probe_handler_t pre_handler, probe_handler_t post_handler, void *handler_data)
Definition: target_os.c:465
#define WHEN_POST
Definition: spf.c:110
int probe_free(struct probe *probe, int force)
Definition: probe.c:777
struct addrspace * space
Definition: target.h:937
int ospecs_len
Definition: spf.c:148
void cleanup_probes()
Definition: spf.c:176
int symbol_type_flags_match(struct symbol *symbol, symbol_type_flag_t flags)
Definition: debug.c:3102
#define TSTATUS(n)
Definition: target_api.h:252
struct target_spec * target_build_default_overlay_spec(struct target *target, tid_t tid)
Definition: target_api.c:734
char * target_name(struct target *target)
Definition: target_api.c:505
char * base_target_id
Definition: dumptarget.c:72
char * srcfile
Definition: spf.c:115
char rt
Definition: spf.c:65
int needtodie
Definition: spf.c:162
struct spf_action::@30::@37 disable
int probe_enable(struct probe *probe)
Definition: probe.c:1861
#define SPF_CONFIGFILE_FATAL
Definition: spf.c:925
Definition: probe.h:308
Definition: spf.c:60
struct spf_action::@30::@34 abort
GList * targets
Definition: spf.c:155
#define vdebug(devel, areas, flags, format,...)
Definition: log.h:302
int when
Definition: spf.c:119
#define SPF_OS_SYSCALL_PROBES
Definition: spf.c:926
int needtodie_exitcode
Definition: spf.c:163
uint8_t disable
Definition: spf.c:120
int apply_config_file(struct spf_config *config)
Definition: spf.c:1525
spf_action_type_t atype
Definition: spf.c:61
struct array_list * target_list_available_tids(struct target *target)
Definition: target_api.c:1272
int evloop_maxsize(struct evloop *evloop)
Definition: evloop.c:191
char * sigdesc
Definition: spf.c:104
void * calloc(size_t nmemb, size_t size)
Definition: debugserver.c:200
struct target_nv_filter * target_nv_filter_parse(char *expr)
long int retval
Definition: spf.c:81
result_t post_handler(struct probe *probe, tid_t tid, void *data, struct probe *trigger, struct probe *base)
Definition: spf.c:908
int target_os_signal_from_name(struct target *target, const char *name)
Definition: target_os.c:411
char * id
Definition: spf.c:87
int probe_disable(struct probe *probe)
Definition: probe.c:1811
struct evloop * evloop_create(evloop_error_handler_t ehandler)
Definition: evloop.c:33
result_t
Definition: common.h:25
struct target * target_lookup_target_id(int id)
Definition: target.c:332
char * tn
Definition: spf.c:66
#define PRIiTID
Definition: common.h:37
int overlay_levels
Definition: spf.c:73
sigset_t ignored
Definition: spf.c:211
Definition: log.h:76
int target_finalize(struct target *target)
Definition: target.c:1955
struct symbol * bsymbol_get_symbol(struct bsymbol *bsymbol)
Definition: symbol.c:66
struct target * target
Definition: probe.h:342
void target_nv_filter_free(struct target_nv_filter *pf)
#define vwarnc(format,...)
Definition: log.h:35
spf_action_type_t
Definition: spf.c:48
char * base_thread_name_or_id
Definition: dumptarget.c:73
char * name
Definition: target_api.h:2521
GList * target_instantiate_and_open(struct target_spec *primary_target_spec, GList *base_target_specs, GList *overlay_target_specs, struct evloop *evloop, GList **error_specs)
Definition: target_api.c:92
int target_open(struct target *target)
Definition: target_api.c:513
#define WHEN_PRE
Definition: spf.c:109
sigset_t exitset
Definition: spf.c:211
void sigh_cleanup_probes(int signo, siginfo_t *siginfo, void *x)
Definition: spf.c:213
#define PRIxADDR
Definition: common.h:67
struct argp spf_argp
Definition: spf.c:984
struct bsymbol * bsymbol
Definition: probe.h:389
int spf_signal(struct target *t, tid_t ctid, char *tiddesc, char *sigdesc)
Definition: spf.c:485
char * overlay_debuginfo_prefix
Definition: spf.c:74
char * symbol_get_name(struct symbol *symbol)
Definition: debug.c:2587
GSList * spf_filter_list
Definition: spf.c:133
void * malloc(size_t size)
Definition: debugserver.c:214
char * debugfile_root_prefix
Definition: target_api.h:2235
struct target_thread * target_lookup_thread(struct target *target, tid_t tid)
Definition: target.c:4023
char ** argv
Definition: spf.c:144
#define array_list_foreach_fakeptr_t(alist, lpc, placeholder, intertype)
Definition: alist.h:381
struct spf_action::@30::@40 signal
char * probe_name(struct probe *probe)
Definition: probe.c:1935
void spf_action_free(struct spf_action *spfa)
Definition: spf.c:1378
int target_os_signal_enqueue(struct target *target, tid_t tid, int signo, void *data)
Definition: target_os.c:399
char * symbol
Definition: spf.c:116
struct target_spec * spec
Definition: dumptarget.c:74
int action_sched(struct probe *probe, struct action *action, action_whence_t whence, action_handler_t handler, void *handler_data)
Definition: probe.c:4119
int main(int argc, char **argv)
Definition: spf.c:988
struct probe * probe
Definition: probe.h:450
#define TID_GLOBAL
Definition: target_api.h:145
int ttdetail
Definition: spf.c:71
struct memregion * region
Definition: target.h:1020
void target_driver_argp_init_children(struct argp_state *state)
Definition: target.c:1057
struct spf_config * config
Definition: spf.c:156
struct target * t
Definition: dumptarget.c:48
uint8_t read_only
Definition: target_api.h:2213