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
target_rpc.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012, 2013, 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 <pthread.h>
20 #include <glib.h>
21 #include <errno.h>
22 #include <sys/prctl.h>
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 #include <unistd.h>
26 
27 #include "config.h"
28 #include "generic_rpc.h"
29 #include "common_xml.h"
30 #include "target_rpc.h"
31 #include "debuginfo_rpc.h"
32 #include "target_xml.h"
33 #include "util.h"
34 #include "alist.h"
35 #include "target.h"
36 #include "target_api.h"
37 #include "probe_api.h"
38 
39 #include "evloop.h"
40 #include "monitor.h"
41 #include "proxyreq.h"
42 
43 #include "target_listener_moduleStub.h"
44 
45 static pthread_mutex_t target_rpc_mutex = PTHREAD_MUTEX_INITIALIZER;
46 static int init_done = 0;
47 
48 extern struct vmi1__DebugFileOptsT defDebugFileOpts;
49 
53 static int target_rpc_monitor_evloop_attach(struct evloop *evloop,void *obj) {
54  struct target *target = (struct target *)obj;
55 
56  if (!obj)
57  return 0;
58 
59  return target_attach_evloop(target,evloop);
60 }
61 
62 static int target_rpc_monitor_evloop_detach(struct evloop *evloop,void *obj) {
63  struct target *target = (struct target *)obj;
64 
65  if (!obj)
66  return 0;
67 
68  return target_detach_evloop(target);
69 }
70 
71 static int target_rpc_monitor_close(struct monitor *monitor,
72  void *obj,void *objstate,
73  int kill,int kill_sig) {
74  struct target *target = (struct target *)obj;
75  int retval;
76 
77  if (!obj)
78  return 0;
79 
80  if ((retval = target_close(target)) != TSTATUS_DONE) {
81  verror("could not close target (error %d)!\n",retval);
82  }
83 
84  return 0;
85 }
86 
87 static int target_rpc_monitor_fini(struct monitor *monitor,
88  void *obj,void *objstate) {
89  struct target *target = (struct target *)obj;
90 
91  if (!obj)
92  return 0;
93 
94  target_free_spec(target->spec);
95  target->spec = NULL;
96  target_finalize(target);
97 
98  return 0;
99 }
100 
101 static int target_rpc_monitor_evloop_is_attached(struct evloop *evloop,void *obj) {
102  struct target *target = (struct target *)obj;
103 
104  if (!obj)
105  return 0;
106 
107  return target_is_evloop_attached(target,evloop);
108 }
109 
110 static int target_rpc_monitor_error(monitor_error_t error,void *obj) {
111  vdebug(5,LA_XML,LF_RPC,"target id %d (error %d)\n",((struct target *)obj)->id,
112  error);
113  return 0;
114 }
115 
116 static int target_rpc_monitor_fatal_error(monitor_error_t error,void *obj) {
117  vdebug(5,LA_XML,LF_RPC,"target id %d (error %d)\n",((struct target *)obj)->id,
118  error);
119  //free(dummy);
120  return 0;
121 }
122 
123 static int target_rpc_monitor_child_recv_msg(struct monitor *monitor,
124  struct monitor_msg *msg) {
125  struct target *target = (struct target *)monitor->obj;
126 
127  vdebug(9,LA_XML,LF_RPC,"msg(%d:%hd,%hd,%d) = '%s' (target %d (%p))\n",
128  msg->id,msg->cmd,msg->seqno,msg->len,msg->msg,msg->objid,target);
129 
130  return proxyreq_recv_request(monitor,msg);
131 }
132 
133 static int target_rpc_monitor_recv_msg(struct monitor *monitor,
134  struct monitor_msg *msg) {
135  struct target *target = (struct target *)monitor->obj;
136 
137  vdebug(9,LA_XML,LF_RPC,"msg(%d:%hd,%hd,%d) = '%s' (target %d (%p))\n",
138  msg->id,msg->cmd,msg->seqno,msg->len,msg->msg,msg->objid,target);
139 
140  return proxyreq_recv_response(monitor,msg);
141 }
142 
143 static int target_rpc_monitor_event(monitor_event_t event,int data,void *obj) {
144  /* XXX: fill in! */
145  return 0;
146 }
147 
149  GHashTable *reftab;
150  struct vmi1__TargetEventT event;
153 };
154 
155 static int _target_generic_rpc_listener_notifier(struct generic_rpc_listener *l,
156  int is_owner,void *data) {
157  result_t retval;
158  struct target_rpc_listener_target_data *ltd = \
159  (struct target_rpc_listener_target_data *)data;
160  int rc;
161 
162  /*
163  * This stinks... but if we were the first
164  */
165 
166  rc = soap_call_vmi1__TargetEventNotification(&l->soap,l->url,NULL,
167  &ltd->event,&ltd->ter);
168  if (rc != SOAP_OK) {
169  if (l->soap.error == SOAP_EOF && l->soap.errnum == 0) {
170  vwarn("timeout notifying %s; removing!",l->url);
171  }
172  else {
173  verrorc("ActionEvent client call failure %s : ",
174  l->url);
175  soap_print_fault(&l->soap,stderr);
176  }
177  /* Let generic_rpc do this... */
178  //soap_closesock(&ltd->soap);
179  return -1;
180  }
181 
182  /*
183  * Take only the owner's response as authoritative.
184  */
185  retval = x_ResultT_to_t_result_t(&l->soap,ltd->ter.result);
186  if (is_owner) {
187  //if (retval > ltd->retval)
188  ltd->retval = retval;
189 
190  vdebug(5,LA_XML,LF_RPC,
191  "notified authoritative listener %s (which returned %d)\n",
192  l->url,retval);
193  }
194  else {
195  vdebug(5,LA_XML,LF_RPC,
196  "notified non-authoritative listener %s (which returned %d)\n",
197  l->url,retval);
198  }
199 
200  if (!l->soap.keep_alive)
201  soap_closesock(&l->soap);
202  /*
203  * Clean up temp/serialization data, but don't kill the sock if we
204  * can avoid it.
205  */
206  soap_destroy(&l->soap);
207  soap_end(&l->soap);
208  //soap_done(&l->soap);
209 
210  return 0;
211 }
212 
213 enum _vmi1__targetEventType
215  switch (chtype) {
216  case T_EVENT_EXITED:
217  return _vmi1__targetEventType__exited;
218  case T_EVENT_EXITING:
219  return _vmi1__targetEventType__exiting;
220  case T_EVENT_ERROR:
221  return _vmi1__targetEventType__error;
222 
224  return _vmi1__targetEventType__osThreadCreated;
226  return _vmi1__targetEventType__osThreadExited;
228  return _vmi1__targetEventType__osThreadExiting;
230  return _vmi1__targetEventType__osSpaceNew;
232  return _vmi1__targetEventType__osSpaceMod;
234  return _vmi1__targetEventType__osSpaceDel;
236  return _vmi1__targetEventType__osRegionNew;
238  return _vmi1__targetEventType__osRegionMod;
240  return _vmi1__targetEventType__osRegionDel;
242  return _vmi1__targetEventType__osRangeNew;
244  return _vmi1__targetEventType__osRangeMod;
246  return _vmi1__targetEventType__osRangeDel;
247 
249  return _vmi1__targetEventType__osProcessThreadCreated;
251  return _vmi1__targetEventType__osProcessThreadExited;
253  return _vmi1__targetEventType__osProcessThreadExiting;
255  return _vmi1__targetEventType__osProcessSpaceNew;
257  return _vmi1__targetEventType__osProcessSpaceMod;
259  return _vmi1__targetEventType__osProcessSpaceDel;
261  return _vmi1__targetEventType__osProcessRegionNew;
263  return _vmi1__targetEventType__osProcessRegionMod;
265  return _vmi1__targetEventType__osProcessRegionDel;
267  return _vmi1__targetEventType__osProcessRangeNew;
269  return _vmi1__targetEventType__osProcessRangeMod;
271  return _vmi1__targetEventType__osProcessRangeDel;
272 
274  return _vmi1__targetEventType__processThreadCreated;
276  return _vmi1__targetEventType__processThreadExited;
278  return _vmi1__targetEventType__processThreadExiting;
280  return _vmi1__targetEventType__processSpaceNew;
282  return _vmi1__targetEventType__processSpaceMod;
284  return _vmi1__targetEventType__processSpaceDel;
286  return _vmi1__targetEventType__processRegionNew;
288  return _vmi1__targetEventType__processRegionMod;
290  return _vmi1__targetEventType__processRegionDel;
292  return _vmi1__targetEventType__processRangeNew;
294  return _vmi1__targetEventType__processRangeMod;
296  return _vmi1__targetEventType__processRangeDel;
297 
298  default:
299  verror("BUG: bad target_event_t %d; returning UINT_MAX\n",
300  chtype);
301  return UINT_MAX;
302  }
303 }
304 
305 static int target_rpc_monitor_notify(void *obj) {
306  struct target *target = (struct target *)obj;
308  struct soap encoder;
309  struct target_event *event;
310  int i;
311 
312  if (!obj)
313  return 0;
314 
315  /*
316  * Don't go to any effort if we don't need to...
317  */
319  return RESULT_SUCCESS;
320 
321  memset(&ltd,0,sizeof(ltd));
322  ltd.retval = RESULT_SUCCESS;
323 
324  /*
325  * NB: cannot call monitor_lock_objtype(MONITOR_OBJTYPE_TARGET)
326  * since our caller might hold &monitor_mutex already!
327  */
328  pthread_mutex_lock(&target_rpc_mutex);
329 
330  /*
331  * We only want to build the gsoap data struct once -- so we have to
332  * set up a temp soap struct to do that on. We can't use the
333  * per-listener soap struct yet cause we don't have it until we're
334  * in the iterator above.
335  */
336  soap_init(&encoder);
337  ltd.reftab = g_hash_table_new_full(g_direct_hash,g_direct_equal,NULL,NULL);
338 
339  /*
340  array_list_foreach(target->state_changes,i,change) {
341  ltd.event.targetEventType =
342  t_target_state_change_type_t_to_x_targetEventType(change->chtype);
343  if (ltd.event.targetEventType == UINT_MAX)
344  continue;
345 
346  ltd.event.tid = target->id;
347  ltd.event.thid = change->tid;
348  ltd.event.targetStatus =
349  t_target_status_t_to_x_TargetStatusT(&encoder,target->status,
350  ltd.reftab,NULL);
351  ltd.event.eventCode = &change->code;
352  ltd.event.eventData = &change->data;
353  ltd.event.eventStartAddr = &change->start;
354  ltd.event.eventEndAddr = &change->end;
355  ltd.event.eventMsg = change->msg;
356 
357  generic_rpc_listener_notify_all(RPC_SVCTYPE_TARGET,target->id,
358  _target_generic_rpc_listener_notifier,
359  &ltd);
360  }
361  */
362 
363  /*
364  * Clean up temp/serialization data, but don't kill the sock if we
365  * can avoid it.
366  */
367  g_hash_table_destroy(ltd.reftab);
368  soap_destroy(&encoder);
369  soap_end(&encoder);
370  soap_done(&encoder);
371 
372  pthread_mutex_unlock(&target_rpc_mutex);
373 
374  return 0;
375 }
376 
378  .evloop_attach = target_rpc_monitor_evloop_attach,
379  .evloop_detach = target_rpc_monitor_evloop_detach,
380  .close = target_rpc_monitor_close,
381  .fini = target_rpc_monitor_fini,
382  .evloop_is_attached = target_rpc_monitor_evloop_is_attached,
383  .child_recv_msg = target_rpc_monitor_child_recv_msg,
384  .recv_msg = target_rpc_monitor_recv_msg,
385  .error = target_rpc_monitor_error,
386  .fatal_error = target_rpc_monitor_fatal_error,
387  .notify = target_rpc_monitor_notify,
388 };
389 
393 void target_rpc_init(void) {
394  pthread_mutex_lock(&target_rpc_mutex);
395 
396  if (init_done) {
397  pthread_mutex_unlock(&target_rpc_mutex);
398  return;
399  }
400 
401  monitor_init();
402  target_init();
405 
407 
409  &target_rpc_monitor_objtype_ops,&target_rpc_mutex);
410 
411  init_done = 1;
412 
413  pthread_mutex_unlock(&target_rpc_mutex);
414 }
415 
416 void target_rpc_fini(void) {
417  void *objid;
418  struct array_list *tlist;
419  int i;
420  struct target *t = NULL;
421  struct monitor *m = NULL;
422 
423  pthread_mutex_lock(&target_rpc_mutex);
424 
425  if (!init_done) {
426  pthread_mutex_unlock(&target_rpc_mutex);
427  return;
428  }
429 
430  pthread_mutex_unlock(&target_rpc_mutex);
431 
432  /* Nuke any existing targets. */
433  tlist =
435 
436  array_list_foreach(tlist,i,objid) {
437  t = NULL;
438  m = NULL;
439  if (!monitor_lookup_objid((int)(uintptr_t)objid,NULL,(void **)&t,&m)
440  || !t)
441  continue;
442  monitor_del_objid(m,(int)(uintptr_t)objid);
444  (int)(uintptr_t)objid);
445  }
446 
448 
451  target_fini();
452  monitor_fini();
453 
454  init_done = 0;
455 
456  pthread_mutex_unlock(&target_rpc_mutex);
457 }
458 
465 int target_rpc_handle_request(struct soap *soap) {
466  return proxyreq_handle_request(soap,"target");
467 }
468 
469 int vmi1__ListTargetTypes(struct soap *soap,
470  void *_,
471  struct vmi1__TargetTypesResponse *r) {
472 #ifdef ENABLE_XENSUPPORT
473  r->__size_targetType = 2;
474 #else
475  r->__size_targetType = 1;
476 #endif
477 
478  r->targetType = \
479  SOAP_CALLOC(soap,r->__size_targetType,sizeof(*(r->targetType)));
480 
481  r->targetType[0] = vmi1__TargetTypeT__ptrace;
482 #ifdef ENABLE_XENSUPPORT
483  r->targetType[1] = vmi1__TargetTypeT__xen;
484 #endif
485 
486  return SOAP_OK;
487 }
488 
489 int vmi1__ListTargets(struct soap *soap,
490  void *_,
491  struct vmi1__TargetsResponse *r) {
492  struct target *target;
493  int i;
494  GHashTable *reftab;
495  struct array_list *tlist;
496 
498  r->__size_target = tlist ? array_list_len(tlist) : 0;
499  if (r->__size_target == 0) {
500  r->target = NULL;
501  if (tlist)
502  array_list_free(tlist);
504  return SOAP_OK;
505  }
506 
507  reftab = g_hash_table_new_full(g_direct_hash,g_direct_equal,NULL,NULL);
508  r->target = SOAP_CALLOC(soap,r->__size_target,sizeof(*r->target));
509  array_list_foreach(tlist,i,target)
510  r->target[i] = t_target_to_x_TargetT(soap,target,reftab,NULL);
511 
512  g_hash_table_destroy(reftab);
513  array_list_free(tlist);
514 
516 
517  return SOAP_OK;
518 }
519 
520 int vmi1__GetTarget(struct soap *soap,
521  vmi1__TargetIdT tid,
522  struct vmi1__TargetResponse *r) {
523  struct target *t = NULL;
524  GHashTable *reftab;
525 
527  (void **)&t,NULL))
528  return soap_receiver_fault(soap,"Nonexistent target!",
529  "Specified target does not exist!");
530 
532  vwarn("load_available_threads failed; ignoring!\n");
533 
534  reftab = g_hash_table_new_full(g_direct_hash,g_direct_equal,NULL,NULL);
535  r->target = t_target_to_x_TargetT(soap,t,reftab,NULL);
536  g_hash_table_destroy(reftab);
537 
539 
540  return SOAP_OK;
541 }
542 
543 int vmi1__GetTargetLogs(struct soap *soap,
544  vmi1__TargetIdT tid,int maxSize,
545  struct vmi1__TargetLogsResponse *r) {
546  struct target *t = NULL;
547  struct monitor *m = NULL;
548  int rc;
549  struct stat statbuf;
550  int fd;
551  int sz;
552 
554  (void **)&t,&m)) {
555  return soap_receiver_fault(soap,"Nonexistent target!",
556  "Specified target does not exist!");
557  }
558 
559  /* NB: don't lock monitor just to read its filenames. Those aren't
560  * deallocated until monitor_destroy() anyway.
561  *
562  * Also, we *do* record the i/o of monitored_target if we forked a
563  * process-monitored target, but right now, we don't try to capture
564  * its logfiles, because we proxy the RPC to the child.
565  */
566 
567  PROXY_REQUEST_LOCKED(soap,tid,&target_rpc_mutex);
568 
569  if (t->spec->outfile) {
570  memset(&statbuf,0,sizeof(statbuf));
571  if (stat(t->spec->outfile,&statbuf))
572  verror("could not stat target stdout logfile %s: %s\n",
573  t->spec->outfile,strerror(errno));
574  else if ((fd = open(t->spec->outfile,O_RDONLY)) < 0) {
575  verror("could not open target stdout logfile %s: %s\n",
576  t->spec->outfile,strerror(errno));
577  }
578  else {
579  r->stdoutLog = SOAP_CALLOC(soap,1,sizeof(*r->stdoutLog));
580  if (statbuf.st_size > 0) {
581  sz = statbuf.st_size;
582  if (maxSize > 0 && maxSize < statbuf.st_size)
583  sz = maxSize;
584  r->stdoutLog->__ptr = SOAP_CALLOC(soap,1,sz);
585  r->stdoutLog->__size = sz;
586 
587  /* Read it all */
588  lseek(fd,statbuf.st_size - sz,SEEK_SET);
589  rc = 0;
590  __SAFE_IO(read,"read",fd,r->stdoutLog->__ptr,sz,rc);
591  if (errno) {
592  vwarn("only read %d of %d bytes for stdoutLog: %s\n",
593  rc,sz,strerror(errno));
594  }
595  if (rc != sz) {
596  vwarn("only read %d of %d bytes for stdoutLog (no error)\n",
597  rc,sz);
598  r->stdoutLog->__size = rc;
599  }
600  }
601  close(fd);
602  }
603  }
604 
605  if (t->spec->errfile) {
606  memset(&statbuf,0,sizeof(statbuf));
607  if (stat(t->spec->errfile,&statbuf))
608  verror("could not stat target stderr logfile %s: %s\n",
609  t->spec->errfile,strerror(errno));
610  else if ((fd = open(t->spec->errfile,O_RDONLY)) < 0) {
611  verror("could not open target stderr logfile %s: %s\n",
612  t->spec->errfile,strerror(errno));
613  }
614  else {
615  r->stderrLog = SOAP_CALLOC(soap,1,sizeof(*r->stderrLog));
616  if (statbuf.st_size > 0) {
617  sz = statbuf.st_size;
618  if (maxSize > 0 && maxSize < statbuf.st_size)
619  sz = maxSize;
620  r->stderrLog->__ptr = SOAP_CALLOC(soap,1,sz);
621  r->stderrLog->__size = sz;
622 
623  /* Read it all */
624  lseek(fd,statbuf.st_size - sz,SEEK_SET);
625  rc = 0;
626  __SAFE_IO(read,"read",fd,r->stderrLog->__ptr,sz,rc);
627  if (rc != sz && errno) {
628  vwarn("only read %d of %d bytes for stderrLog: %s\n",
629  rc,sz,strerror(errno));
630  }
631  else if (rc != sz) {
632  vwarn("only read %d of %d bytes for stderrLog (no error)\n",
633  rc,sz);
634  r->stderrLog->__size = rc;
635  }
636  }
637  close(fd);
638  }
639  }
640 
641  /* XXX: don't do this for now; later, fix GetTargetLogs to not be
642  * proxied and just do it all from the server. BUT, right now, the
643  * server doesn't have access to the target->spec->logfile names, so
644  * it can't try to read them. If we were saving monitored object
645  * metadata better, this would be easier...
646  */
647 
648  /*
649  if (m->type == MONITOR_TYPE_PROCESS
650  && m->p.stdout_logfile) {
651  memset(&statbuf,0,sizeof(statbuf));
652  if (stat(m->p.stdout_logfile,&statbuf))
653  verror("could not stat dedicated monitor stdout logfile %s: %s\n",
654  m->p.stdout_logfile,strerror(errno));
655  else if ((fd = open(m->p.stdout_logfile,O_RDONLY)) < 0) {
656  verror("could not open dedicated monitor stdout logfile %s: %s\n",
657  m->p.stdout_logfile,strerror(errno));
658  }
659  else {
660  r->dedicatedMonitorStdoutLog =
661  SOAP_CALLOC(soap,1,sizeof(*r->dedicatedMonitorStdoutLog));
662  if (statbuf.st_size > 0) {
663  sz = statbuf.st_size;
664  if (maxSize > 0 && maxSize < statbuf.st_size)
665  sz = maxSize;
666  r->dedicatedMonitorStdoutLog->__ptr = SOAP_CALLOC(soap,1,sz);
667  r->dedicatedMonitorStdoutLog->__size = sz;
668 
669  lseek(fd,statbuf.st_size - sz,SEEK_SET);
670  rc = 0;
671  __SAFE_IO(read,"read",fd,r->dedicatedMonitorStdoutLog->__ptr,sz,rc);
672  if (errno) {
673  vwarn("only read %d of %d bytes for"
674  " dedicatedMonitorStdoutLog: %s\n",
675  rc,sz,strerror(errno));
676  }
677  if (rc != sz) {
678  vwarn("only read %d of %d bytes for"
679  " dedicatedMonitorStdoutLog (no error)\n",
680  rc,sz);
681  r->dedicatedMonitorStdoutLog->__size = rc;
682  }
683  }
684  close(fd);
685  }
686  }
687 
688  if (m->type == MONITOR_TYPE_PROCESS
689  && m->p.stderr_logfile) {
690  memset(&statbuf,0,sizeof(statbuf));
691  if (stat(m->p.stderr_logfile,&statbuf))
692  verror("could not stat dedicated monitor stderr logfile %s: %s\n",
693  m->p.stderr_logfile,strerror(errno));
694  else if ((fd = open(m->p.stderr_logfile,O_RDONLY)) < 0) {
695  verror("could not open dedicated monitor stderr logfile %s: %s\n",
696  m->p.stderr_logfile,strerror(errno));
697  }
698  else {
699  r->dedicatedMonitorStderrLog =
700  SOAP_CALLOC(soap,1,sizeof(*r->dedicatedMonitorStderrLog));
701  if (statbuf.st_size > 0) {
702  sz = statbuf.st_size;
703  if (maxSize > 0 && maxSize < statbuf.st_size)
704  sz = maxSize;
705  r->dedicatedMonitorStderrLog->__ptr = SOAP_CALLOC(soap,1,sz);
706  r->dedicatedMonitorStderrLog->__size = sz;
707 
708  lseek(fd,statbuf.st_size - sz,SEEK_SET);
709  rc = 0;
710  __SAFE_IO(read,"read",fd,r->dedicatedMonitorStderrLog->__ptr,sz,rc);
711  if (errno) {
712  vwarn("only read %d of %d bytes for"
713  " dedicatedMonitorStderrLog: %s\n",
714  rc,sz,strerror(errno));
715  }
716  if (rc != sz) {
717  vwarn("only read %d of %d bytes for"
718  " dedicatedMonitorStderrLog (no error)\n",
719  rc,sz);
720  r->dedicatedMonitorStderrLog->__size = rc;
721  }
722  }
723  close(fd);
724  }
725  }
726  */
727 
729 
730  return SOAP_OK;
731 }
732 
733 int vmi1__InstantiateTarget(struct soap *soap,
734  struct vmi1__TargetSpecT *spec,
735  vmi1__ListenerT *ownerListener,
736  struct vmi1__TargetResponse *r) {
737  struct target *t;
738  struct target_spec *s;
739  GHashTable *reftab;
740  struct monitor *monitor;
741  struct proxyreq *pr;
742  int tid;
743  int largc = 0;
744  char **largv = NULL;
745  int i;
746  char *tmpbuf;
747  int tmpbuflen;
748  int pid;
749  char *url = NULL;
750  int len = 0;
751  int rn;
752 
753  pr = soap->user;
754  if (!pr) {
755  return soap_receiver_fault(soap,
756  "Request needed splitting but not split!",
757  "Request needed splitting but not split!");
758  }
759 
760  if (ownerListener) {
761  if (ownerListener->url != NULL)
762  url = ownerListener->url;
763  else if (ownerListener->hostname != NULL
764  && ownerListener->port != NULL) {
765  len = sizeof("http://") + strlen(ownerListener->hostname) \
766  + sizeof(":") + 11 + sizeof(":/vmi/1/targetListener") + 1;
767  url = malloc(len * sizeof(char));
768  sprintf(url,"http://%s:%d/vmi/1/targetListener",
769  ownerListener->hostname,*ownerListener->port);
770  }
771  else {
772  return soap_receiver_fault(soap,"Bad listener!","Bad listener!");
773  }
774  }
775 
776  reftab = g_hash_table_new_full(g_direct_hash,g_direct_equal,NULL,NULL);
777 
778  s = x_TargetSpecT_to_t_target_spec(soap,spec,reftab,NULL);
779  if (!s) {
780  g_hash_table_destroy(reftab);
781  return soap_receiver_fault(soap,"Bad target spec!",
782  "Bad target spec!");
783  }
784 
786 
787  tid = monitor_get_unique_objid();
788  /* Force it to use our new monitored object id. */
789  s->target_id = tid;
790 
791  rn = rand();
792 
793  /*
794  * Have to see if we need to fork this target, or spawn it in a
795  * thread. For now, just always spawn in a thread.
796  */
797  if (!spec->dedicatedMonitor
798  || (spec->dedicatedMonitor
799  && *spec->dedicatedMonitor == xsd__boolean__false_)) {
800  /*
801  * At this point, we need to create a monitor object associated with
802  * this thread's new target; then create an evloop, attach it to our
803  * new target and to the monitor; and call evloop_run infinitely --
804  * only destroying the target and the monitor if a fatal error
805  * occurs.
806  *
807  * Instead of even bothering to "share" soap struct state between
808  * incoming requests and request monitor threads that are directly
809  * attached to a target, we should always follow the model that we
810  * would use for forking: record the request, signal the monitor
811  * thread by copying the request over the pipe to the monitor
812  * thread; and block the client handling thread on the monitor
813  * thread serving the request. Monitors have to handle requests
814  * serially anyway (well, at least operations on a target; debuginfo
815  * operations might be another story and could be parallelized).
816  *
817  * So this means no more queues; no more shared soap structs; all
818  * soap structs are faked if the request is split;
819  * requests/responses are fully buffered over pipes (sigh) (well,
820  * can we chain the read/write functions direct so they don't have
821  * to? but does soap really buffer the whole response before
822  * writing it? it would have to in order to write the
823  * content-header line...) (so, let's start out with full buffering,
824  * then later we could break pipe comms into well-known packet lengths
825  * with a length header field, then data).
826  *
827  * Debuginfo responses are big and huge and we have to do something
828  * better than querying the debuginfo per-target... unless gsoap
829  * really buffers the entire result before writing anything. If it
830  * does, we may as well double-buffer :). It would just be best to
831  * figure a way to share the buffer to avoid all the mallocs in the
832  * second buffering when passing a result back.
833  */
835  tid,MONITOR_OBJTYPE_TARGET,NULL,NULL);
836  if (!monitor) {
837  target_free_spec(s);
838  g_hash_table_destroy(reftab);
840  return soap_receiver_fault(soap,"Could not create monitor!",
841  "Could not create monitor!");
842  }
843 
844  /*
845  * NB: let target API handle stdout/err if the client wants it
846  * logged; just provide it valid tmpfile names.
847  */
848  if (spec->logStdout && *spec->logStdout == xsd__boolean__true_) {
849  tmpbuflen = strlen(GENERIC_RPC_TMPDIR) + 1 + 11 + 1 + 11
850  + sizeof(".stdout.log") + 1;
851  tmpbuf = malloc(tmpbuflen);
852  snprintf(tmpbuf,tmpbuflen,"%s/%d.%d.stdout.log",
854 
855  s->outfile = tmpbuf;
856  }
857 
858  if (spec->logStderr && *spec->logStderr == xsd__boolean__true_) {
859  tmpbuflen = strlen(GENERIC_RPC_TMPDIR) + 1 + 11 + 1 + 11
860  + sizeof(".stderr.log") + 1;
861  tmpbuf = malloc(tmpbuflen);
862  snprintf(tmpbuf,tmpbuflen,"%s/%d.%d.stderr.log",
864 
865  s->errfile = tmpbuf;
866  }
867 
868  /* Make sure to use our new evloop right away. */
869  t = target_instantiate(s,monitor->evloop);
870  if (!t) {
871  target_free_spec(s);
872  g_hash_table_destroy(reftab);
874  return soap_receiver_fault(soap,"Could not instantiate target!",
875  "Could not instantiate target!");
876  }
877 
879 
880  if (target_open(t)) {
881  verror("could not open target!\n");
882  target_finalize(t);
883  target_free_spec(s);
884  g_hash_table_destroy(reftab);
886  return soap_receiver_fault(soap,"Could not open target!",
887  "Could not open target after"
888  " instantiating it successfully!");
889  }
890 
891  proxyreq_attach_new_objid(pr,t->id,monitor);
892 
893  if (url) {
895  url,t->id,1))
896  vwarn("could not bind target %d to listener %s!?\n",
897  t->id,url);
898  }
899 
901  vwarn("load_available_threads failed; ignoring!\n");
902 
903  r->target = t_target_to_x_TargetT(soap,t,reftab,NULL);
905 
906  return SOAP_OK;
907  }
908  else {
909  /* Use our special servetarget program to fork the target. */
910  if (target_spec_to_argv(s,MONITORED_TARGET_LAUNCHER,&largc,&largv)) {
911  target_free_spec(s);
912  g_hash_table_destroy(reftab);
914  return soap_receiver_fault(soap,"Could not create argv from spec!",
915  "Could not create argv from spec!");
916  }
917 
919  s->target_id,MONITOR_OBJTYPE_TARGET,NULL,NULL);
920  if (!monitor) {
921  if (largc > 0) {
922  for (i = 0; i < largc; ++i)
923  if (largv[i])
924  free(largv[i]);
925  free(largv);
926  }
927  monitor_destroy(monitor);
928  target_free_spec(s);
929  g_hash_table_destroy(reftab);
931  return soap_receiver_fault(soap,"Could not create monitor!",
932  "Could not create monitor!");
933  }
934 
935  /*
936  * Setup I/O to child! We always have to use our callbacks and
937  * do our own logging. BUT, we want to log/interact with the
938  * spawned target's I/O, not to the child process that is
939  * launching the child. Unfortunately, this is more
940  * time-consuming to implement, so, for now, just ensure that
941  * the target gets launched using the child's I/O streams --
942  * which our callbacks here will listen to. It's either do that
943  * or open additional streams that we tell the child about.
944  *
945  * So, for now, we just use the monitor's I/O abstractions, just
946  * like if we were spawning an analysis.
947  */
948  /* Hack the spec to get the target to use the child's FDs.*/
949 
950  if (spec->stdinBytes && spec->stdinBytes->__size > 0) {
951  s->infile = strdup("-");
952 
953  tmpbuf = malloc(spec->stdinBytes->__size);
954  memcpy(tmpbuf,spec->stdinBytes->__ptr,spec->stdinBytes->__size);
955 
956  monitor_setup_stdin(monitor,tmpbuf,spec->stdinBytes->__size);
957  }
958 
959  if (spec->logStdout && *spec->logStdout == xsd__boolean__true_) {
960  //s->outfile = strdup("-");
961 
962  tmpbuflen = strlen(GENERIC_RPC_TMPDIR) + 1 + 11 + 1 + 11
963  + sizeof(".stdout.log") + 1;
964  tmpbuf = malloc(tmpbuflen);
965  snprintf(tmpbuf,tmpbuflen,"%s/%d.%d.stdout.log",
967  s->outfile = tmpbuf;
968 
969  tmpbuflen = strlen(GENERIC_RPC_TMPDIR) + 1 + 11 + 1 + 11
970  + sizeof(".dedicatedMonitor.stdout.log") + 1;
971  tmpbuf = malloc(tmpbuflen);
972  snprintf(tmpbuf,tmpbuflen,"%s/%d.%d.dedicatedMonitor.stdout.log",
974 
975  monitor_setup_stdout(monitor,-1,tmpbuf,NULL,NULL);
976  free(tmpbuf);
977  }
978 
979  if (spec->logStderr && *spec->logStderr == xsd__boolean__true_) {
980  //s->errfile = strdup("-");
981 
982  tmpbuflen = strlen(GENERIC_RPC_TMPDIR) + 1 + 11 + 1 + 11
983  + sizeof(".stderr.log") + 1;
984  tmpbuf = malloc(tmpbuflen);
985  snprintf(tmpbuf,tmpbuflen,"%s/%d.%d.stderr.log",
987  s->errfile = tmpbuf;
988 
989  tmpbuflen = strlen(GENERIC_RPC_TMPDIR) + 1 + 11 + 1 + 11
990  + sizeof(".dedicatedMonitor.stderr.log") + 1;
991  tmpbuf = malloc(tmpbuflen);
992  snprintf(tmpbuf,tmpbuflen,"%s/%d.%d.dedicatedMonitor.stderr.log",
994 
995  monitor_setup_stderr(monitor,-1,tmpbuf,NULL,NULL);
996  free(tmpbuf);
997  }
998 
1000 
1001  pid = monitor_spawn(monitor,MONITORED_TARGET_LAUNCHER,largv,NULL,
1003  if (pid < 0) {
1004  verror("error spawning: %d (%s)\n",pid,strerror(errno));
1005  if (largc > 0) {
1006  for (i = 0; i < largc; ++i)
1007  if (largv[i])
1008  free(largv[i]);
1009  free(largv);
1010  }
1011  monitor_destroy(monitor);
1012  target_free_spec(s);
1013  g_hash_table_destroy(reftab);
1015  return soap_receiver_fault(soap,"Could not spawn forked target!",
1016  "Could not spawn forked target!");
1017  }
1018 
1019  proxyreq_attach_new_objid(pr,s->target_id,monitor);
1020 
1021  r->target = t_target_id_to_x_TargetT(soap,s->target_id,s,reftab,NULL);
1023 
1024  return SOAP_OK;
1025  }
1026 }
1027 
1029  vmi1__TargetIdT utid,
1030  vmi1__ThreadIdT thid,
1031  struct vmi1__TargetSpecT *spec,
1032  vmi1__ListenerT *ownerListener,
1033  struct vmi1__TargetResponse *r) {
1034  struct target *t;
1035  struct target_spec *s;
1036  GHashTable *reftab;
1037  struct monitor *monitor;
1038  struct proxyreq *pr;
1039  int tid;
1040  int largc = 0;
1041  char **largv = NULL;
1042  int i;
1043  char *tmpbuf;
1044  int tmpbuflen;
1045  int pid;
1046  char *url = NULL;
1047  int len = 0;
1048  int rn;
1049  struct target *ut;
1050 
1051  pr = soap->user;
1052  if (!pr) {
1053  return soap_receiver_fault(soap,
1054  "Request needed splitting but not split!",
1055  "Request needed splitting but not split!");
1056  }
1057 
1058  if (spec->dedicatedMonitor && *spec->dedicatedMonitor == xsd__boolean__true_)
1059  return soap_receiver_fault(soap,
1060  "Overlays do not support dedicated mode!",
1061  "Overlays do not support dedicated mode!");
1062 
1064  (void **)&ut,&monitor)) {
1065  return soap_receiver_fault(soap,"Nonexistent underlying target!",
1066  "Specified underlying target does not exist!");
1067  }
1068 
1069  if (ownerListener) {
1070  if (ownerListener->url != NULL)
1071  url = ownerListener->url;
1072  else if (ownerListener->hostname != NULL
1073  && ownerListener->port != NULL) {
1074  len = sizeof("http://") + strlen(ownerListener->hostname) \
1075  + sizeof(":") + 11 + sizeof(":/vmi/1/targetListener") + 1;
1076  url = malloc(len * sizeof(char));
1077  sprintf(url,"http://%s:%d/vmi/1/targetListener",
1078  ownerListener->hostname,*ownerListener->port);
1079  }
1080  else {
1081  return soap_receiver_fault(soap,"Bad listener!","Bad listener!");
1082  }
1083  }
1084 
1085  reftab = g_hash_table_new_full(g_direct_hash,g_direct_equal,NULL,NULL);
1086 
1087  s = x_TargetSpecT_to_t_target_spec(soap,spec,reftab,NULL);
1088  if (!s) {
1089  g_hash_table_destroy(reftab);
1090  return soap_receiver_fault(soap,"Bad target spec!",
1091  "Bad target spec!");
1092  }
1093 
1094  /* NB: don't lock monitor just to read its filenames. Those aren't
1095  * deallocated until monitor_destroy() anyway.
1096  *
1097  * Also, we *do* record the i/o of monitored_target if we forked a
1098  * process-monitored target, but right now, we don't try to capture
1099  * its logfiles, because we proxy the RPC to the child.
1100  */
1101 
1102  PROXY_REQUEST_LOCKED(soap,utid,&target_rpc_mutex);
1103 
1104  tid = monitor_get_unique_objid();
1105  /* Force it to use our new monitored object id. */
1106  s->target_id = tid;
1107 
1108  rn = rand();
1109 
1110  /*
1111  * Have to see if we need to fork this target, or spawn it in a
1112  * thread. For now, just always spawn in a thread.
1113  */
1114  if (!spec->dedicatedMonitor
1115  || (spec->dedicatedMonitor
1116  && *spec->dedicatedMonitor == xsd__boolean__false_)) {
1117  /*
1118  * NB: let target API handle stdout/err if the client wants it
1119  * logged; just provide it valid tmpfile names.
1120  */
1121  if (spec->logStdout && *spec->logStdout == xsd__boolean__true_) {
1122  tmpbuflen = strlen(GENERIC_RPC_TMPDIR) + 1 + 11 + 1 + 11
1123  + sizeof(".stdout.log") + 1;
1124  tmpbuf = malloc(tmpbuflen);
1125  snprintf(tmpbuf,tmpbuflen,"%s/%d.%d.stdout.log",
1127 
1128  s->outfile = tmpbuf;
1129  }
1130 
1131  if (spec->logStderr && *spec->logStderr == xsd__boolean__true_) {
1132  tmpbuflen = strlen(GENERIC_RPC_TMPDIR) + 1 + 11 + 1 + 11
1133  + sizeof(".stderr.log") + 1;
1134  tmpbuf = malloc(tmpbuflen);
1135  snprintf(tmpbuf,tmpbuflen,"%s/%d.%d.stderr.log",
1137 
1138  s->errfile = tmpbuf;
1139  }
1140 
1141  /* Make sure to use our new evloop right away. */
1142  t = target_instantiate_overlay(ut,thid,s);
1143  if (!t) {
1144  target_free_spec(s);
1145  g_hash_table_destroy(reftab);
1147  return soap_receiver_fault(soap,"Could not instantiate target!",
1148  "Could not instantiate target!");
1149  }
1150 
1151  monitor_add_obj(monitor,t->id,MONITOR_OBJTYPE_TARGET,t,NULL);
1152 
1153  if (target_open(t)) {
1154  verror("could not open target!\n");
1155  target_finalize(t);
1156  target_free_spec(s);
1157  g_hash_table_destroy(reftab);
1159  return soap_receiver_fault(soap,"Could not open target!",
1160  "Could not open target after"
1161  " instantiating it successfully!");
1162  }
1163 
1165  vwarn("load_available_threads failed; ignoring!\n");
1166 
1167  proxyreq_attach_new_objid(pr,t->id,monitor);
1168 
1169  if (url) {
1171  url,t->id,1))
1172  vwarn("could not bind target %d to listener %s!?\n",
1173  t->id,url);
1174  }
1175 
1176  r->target = t_target_to_x_TargetT(soap,t,reftab,NULL);
1178 
1179  return SOAP_OK;
1180  }
1181 }
1182 
1183 int vmi1__PauseTarget(struct soap *soap,
1184  vmi1__TargetIdT tid,
1185  struct vmi1__NoneResponse *r) {
1186  struct target *t = NULL;
1187 
1189  (void **)&t,NULL)) {
1190  return soap_receiver_fault(soap,"Nonexistent target!",
1191  "Specified target does not exist!");
1192  }
1193 
1194  PROXY_REQUEST_LOCKED(soap,tid,&target_rpc_mutex);
1195 
1196  if (target_pause(t)) {
1198  return soap_receiver_fault(soap,"Could not pause target!",
1199  "Could not pause target!");
1200  }
1201 
1203 
1204  return SOAP_OK;
1205 }
1206 
1207 int vmi1__ResumeTarget(struct soap *soap,
1208  vmi1__TargetIdT tid,
1209  struct vmi1__NoneResponse *r) {
1210  struct target *t = NULL;
1211 
1213  (void **)&t,NULL)) {
1214  return soap_receiver_fault(soap,"Nonexistent target!",
1215  "Specified target does not exist!");
1216  }
1217 
1218  PROXY_REQUEST_LOCKED(soap,tid,&target_rpc_mutex);
1219 
1220  if (target_resume(t)) {
1222  return soap_receiver_fault(soap,"Could not resume target!",
1223  "Could not resume target!");
1224  }
1225 
1227 
1228  return SOAP_OK;
1229 }
1230 
1231 int vmi1__CloseTarget(struct soap *soap,
1232  vmi1__TargetIdT tid,
1233  struct vmi1__NoneResponse *r) {
1234  struct target *t = NULL;
1235  struct monitor *monitor;
1236 
1238  (void **)&t,&monitor)) {
1239  return soap_receiver_fault(soap,"Nonexistent target!",
1240  "Specified target does not exist!");
1241  }
1242 
1243  PROXY_REQUEST_LOCKED(soap,tid,&target_rpc_mutex);
1244 
1245  /*
1246  * Let the monitor close/kill the target.
1247  */
1248  monitor_close_obj(monitor,t,0,0);
1249 
1251 
1252  return SOAP_OK;
1253 }
1254 
1255 int vmi1__KillTarget(struct soap *soap,
1256  vmi1__TargetIdT tid,int kill_sig,
1257  struct vmi1__NoneResponse *r) {
1258  struct target *t = NULL;
1259  struct monitor *monitor;
1260 
1262  (void **)&t,&monitor)) {
1263  return soap_receiver_fault(soap,"Nonexistent target!",
1264  "Specified target does not exist!");
1265  }
1266 
1267  PROXY_REQUEST_LOCKED(soap,tid,&target_rpc_mutex);
1268 
1269  /*
1270  * Override whatever the default was!
1271  */
1272  t->spec->kill_on_close = 1;
1273  t->spec->kill_on_close_sig = kill_sig;
1274 
1275  /*
1276  * Let the monitor close/kill the target.
1277  */
1278  monitor_close_obj(monitor,t,0,0);
1279 
1281 
1282  return SOAP_OK;
1283 }
1284 
1285 int vmi1__FinalizeTarget(struct soap *soap,
1286  vmi1__TargetIdT tid,
1287  struct vmi1__NoneResponse *r) {
1288  struct target *t = NULL;
1289  struct monitor *monitor = NULL;
1290 
1292  (void **)&t,&monitor)) {
1293  return soap_receiver_fault(soap,"Nonexistent target!",
1294  "Specified target does not exist!");
1295  }
1296 
1297  PROXY_REQUEST_LOCKED(soap,tid,&target_rpc_mutex);
1298 
1299  monitor_del_obj(monitor,t);
1300 
1302 
1303  return SOAP_OK;
1304 }
1305 
1306 int vmi1__PauseThread(struct soap *soap,
1307  vmi1__TargetIdT tid,vmi1__ThreadIdT thid,
1308  struct vmi1__NoneResponse *r) {
1309  struct target *t = NULL;
1310 
1312  (void **)&t,NULL)) {
1313  return soap_receiver_fault(soap,"Nonexistent target!",
1314  "Specified target does not exist!");
1315  }
1316 
1317  PROXY_REQUEST_LOCKED(soap,tid,&target_rpc_mutex);
1318 
1319  if (target_pause_thread(t,thid,0)) {
1321  return soap_receiver_fault(soap,"Could not pause target thread!",
1322  "Could not pause target thread!");
1323  }
1324 
1326 
1327  return SOAP_OK;
1328 }
1329 
1330 int vmi1__LookupTargetSymbolSimple(struct soap *soap,
1331  vmi1__TargetIdT tid,char *name,
1332  struct vmi1__DebugFileOptsT *opts,
1333  struct vmi1__SymbolResponse *r) {
1334  struct bsymbol *bsymbol;
1335  GHashTable *reftab;
1336  struct array_list *refstack;
1337  struct target *t = NULL;
1338 
1340  (void **)&t,NULL)) {
1341  return soap_receiver_fault(soap,"Nonexistent target!",
1342  "Specified target does not exist!");
1343  }
1344 
1345  PROXY_REQUEST_LOCKED(soap,tid,&target_rpc_mutex);
1346 
1347  if (!opts)
1348  opts = &defDebugFileOpts;
1349 
1350  if (opts->doMultiRef)
1351  soap_set_omode(soap,SOAP_XML_GRAPH);
1352 
1353  bsymbol = target_lookup_sym(t,name,NULL,NULL,SYMBOL_TYPE_NONE);
1354 
1355  if (!bsymbol) {
1357  return soap_receiver_fault(soap,"Could not find symbol!",
1358  "Could not find symbol!");
1359  }
1360 
1361  reftab = g_hash_table_new_full(g_direct_hash,g_direct_equal,NULL,NULL);
1362  refstack = array_list_create(DEF_REFSTACK_SIZE);
1363 
1364  r->symbol = d_symbol_to_x_SymbolT(soap,bsymbol->lsymbol->symbol,
1365  opts,reftab,refstack,0);
1366 
1367  array_list_free(refstack);
1368  g_hash_table_destroy(reftab);
1369 
1370  bsymbol_release(bsymbol);
1371 
1373 
1374  return SOAP_OK;
1375 }
1376 
1377 int vmi1__LookupTargetSymbol(struct soap *soap,
1378  vmi1__TargetIdT tid,char *name,
1379  struct vmi1__DebugFileOptsT *opts,
1380  struct vmi1__NestedSymbolResponse *r) {
1381  struct bsymbol *bsymbol;
1382  GHashTable *reftab;
1383  struct array_list *refstack;
1384  struct target *t = NULL;
1385 
1387  (void **)&t,NULL)) {
1388  return soap_receiver_fault(soap,"Nonexistent target!",
1389  "Specified target does not exist!");
1390  }
1391 
1392  PROXY_REQUEST_LOCKED(soap,tid,&target_rpc_mutex);
1393 
1394  if (!opts)
1395  opts = &defDebugFileOpts;
1396 
1397  if (opts->doMultiRef)
1398  soap_set_omode(soap,SOAP_XML_GRAPH);
1399 
1400  bsymbol = target_lookup_sym(t,name,NULL,NULL,SYMBOL_TYPE_NONE);
1401 
1402  if (!bsymbol) {
1404  return soap_receiver_fault(soap,"Could not find symbol!",
1405  "Could not find symbol!");
1406  }
1407 
1408  reftab = g_hash_table_new_full(g_direct_hash,g_direct_equal,NULL,NULL);
1409  refstack = array_list_create(DEF_REFSTACK_SIZE);
1410  r->nestedSymbol = \
1412  opts,reftab,refstack,0);
1413  if (r->nestedSymbol)
1414  vwarn("%d %d %p\n",g_hash_table_size(reftab),
1415  r->nestedSymbol->__size_SymbolsT,
1416  r->nestedSymbol->__union_SymbolsT);
1417  else
1418  vwarn("%d\n",g_hash_table_size(reftab));
1419 
1420  array_list_free(refstack);
1421  g_hash_table_destroy(reftab);
1422 
1423  bsymbol_release(bsymbol);
1424 
1426 
1427  return SOAP_OK;
1428 }
1429 
1430 int vmi1__LookupTargetAddrSimple(struct soap *soap,
1431  vmi1__TargetIdT tid,vmi1__ADDR addr,
1432  struct vmi1__DebugFileOptsT *opts,
1433  struct vmi1__SymbolResponse *r) {
1434  struct bsymbol *bsymbol;
1435  GHashTable *reftab;
1436  struct array_list *refstack;
1437  struct target *t = NULL;
1438 
1440  (void **)&t,NULL)) {
1441  return soap_receiver_fault(soap,"Nonexistent target!",
1442  "Specified target does not exist!");
1443  }
1444 
1445  PROXY_REQUEST_LOCKED(soap,tid,&target_rpc_mutex);
1446 
1447  if (!opts)
1448  opts = &defDebugFileOpts;
1449 
1450  if (opts->doMultiRef)
1451  soap_set_omode(soap,SOAP_XML_GRAPH);
1452 
1453  bsymbol = target_lookup_sym_addr(t,addr);
1454 
1455  if (!bsymbol) {
1457  return soap_receiver_fault(soap,"Could not find address!",
1458  "Could not find address!");
1459  }
1460 
1461  reftab = g_hash_table_new_full(g_direct_hash,g_direct_equal,NULL,NULL);
1462  refstack = array_list_create(DEF_REFSTACK_SIZE);
1463 
1464  r->symbol = d_symbol_to_x_SymbolT(soap,bsymbol->lsymbol->symbol,
1465  opts,reftab,refstack,0);
1466 
1467  array_list_free(refstack);
1468  g_hash_table_destroy(reftab);
1469 
1470  bsymbol_release(bsymbol);
1471 
1473 
1474  return SOAP_OK;
1475 }
1476 
1477 int vmi1__LookupTargetAddr(struct soap *soap,
1478  vmi1__TargetIdT tid,vmi1__ADDR addr,
1479  struct vmi1__DebugFileOptsT *opts,
1480  struct vmi1__NestedSymbolResponse *r) {
1481  struct bsymbol *bsymbol;
1482  GHashTable *reftab;
1483  struct array_list *refstack;
1484  struct target *t = NULL;
1485 
1487  (void **)&t,NULL)) {
1488  return soap_receiver_fault(soap,"Nonexistent target!",
1489  "Specified target does not exist!");
1490  }
1491 
1492  PROXY_REQUEST_LOCKED(soap,tid,&target_rpc_mutex);
1493 
1494  if (!opts)
1495  opts = &defDebugFileOpts;
1496 
1497  if (opts->doMultiRef)
1498  soap_set_omode(soap,SOAP_XML_GRAPH);
1499 
1500  bsymbol = target_lookup_sym_addr(t,addr);
1501 
1502  if (!bsymbol) {
1504  return soap_receiver_fault(soap,"Could not find address!",
1505  "Could not find address!");
1506  }
1507 
1508  reftab = g_hash_table_new_full(g_direct_hash,g_direct_equal,NULL,NULL);
1509  refstack = array_list_create(DEF_REFSTACK_SIZE);
1510  r->nestedSymbol = \
1512  opts,reftab,refstack,0);
1513  if (r->nestedSymbol)
1514  vwarn("%d %d %p\n",g_hash_table_size(reftab),
1515  r->nestedSymbol->__size_SymbolsT,
1516  r->nestedSymbol->__union_SymbolsT);
1517  else
1518  vwarn("%d\n",g_hash_table_size(reftab));
1519 
1520  array_list_free(refstack);
1521  g_hash_table_destroy(reftab);
1522 
1523  bsymbol_release(bsymbol);
1524 
1526 
1527  return SOAP_OK;
1528 }
1529 
1530 int vmi1__LookupTargetLineSimple(struct soap *soap,
1531  vmi1__TargetIdT tid,char *filename,int line,
1532  struct vmi1__DebugFileOptsT *opts,
1533  struct vmi1__SymbolResponse *r) {
1534  struct bsymbol *bsymbol;
1535  GHashTable *reftab;
1536  struct array_list *refstack;
1537  struct target *t = NULL;
1538 
1540  (void **)&t,NULL)) {
1541  return soap_receiver_fault(soap,"Nonexistent target!",
1542  "Specified target does not exist!");
1543  }
1544 
1545  PROXY_REQUEST_LOCKED(soap,tid,&target_rpc_mutex);
1546 
1547  if (!opts)
1548  opts = &defDebugFileOpts;
1549 
1550  if (opts->doMultiRef)
1551  soap_set_omode(soap,SOAP_XML_GRAPH);
1552 
1553  bsymbol = target_lookup_sym_line(t,filename,line,NULL,NULL);
1554 
1555  if (!bsymbol) {
1557  return soap_receiver_fault(soap,"Could not find line!",
1558  "Could not find line!");
1559  }
1560 
1561  reftab = g_hash_table_new_full(g_direct_hash,g_direct_equal,NULL,NULL);
1562  refstack = array_list_create(DEF_REFSTACK_SIZE);
1563 
1564  r->symbol = d_symbol_to_x_SymbolT(soap,bsymbol->lsymbol->symbol,
1565  opts,reftab,refstack,0);
1566 
1567  array_list_free(refstack);
1568  g_hash_table_destroy(reftab);
1569 
1570  bsymbol_release(bsymbol);
1571 
1573 
1574  return SOAP_OK;
1575 
1576 }
1577 
1578 int vmi1__LookupTargetLine(struct soap *soap,
1579  vmi1__TargetIdT tid,char *filename,int line,
1580  struct vmi1__DebugFileOptsT *opts,
1581  struct vmi1__NestedSymbolResponse *r) {
1582  struct bsymbol *bsymbol;
1583  GHashTable *reftab;
1584  struct array_list *refstack;
1585  struct target *t = NULL;
1586 
1588  (void **)&t,NULL)) {
1589  return soap_receiver_fault(soap,"Nonexistent target!",
1590  "Specified target does not exist!");
1591  }
1592 
1593  PROXY_REQUEST_LOCKED(soap,tid,&target_rpc_mutex);
1594 
1595  if (!opts)
1596  opts = &defDebugFileOpts;
1597 
1598  if (opts->doMultiRef)
1599  soap_set_omode(soap,SOAP_XML_GRAPH);
1600 
1601  bsymbol = target_lookup_sym_line(t,filename,line,NULL,NULL);
1602 
1603  if (!bsymbol) {
1605  return soap_receiver_fault(soap,"Could not find line!",
1606  "Could not find line!");
1607  }
1608 
1609  reftab = g_hash_table_new_full(g_direct_hash,g_direct_equal,NULL,NULL);
1610  refstack = array_list_create(DEF_REFSTACK_SIZE);
1611  r->nestedSymbol = \
1613  opts,reftab,refstack,0);
1614  if (r->nestedSymbol)
1615  vwarn("%d %d %p\n",g_hash_table_size(reftab),
1616  r->nestedSymbol->__size_SymbolsT,
1617  r->nestedSymbol->__union_SymbolsT);
1618  else
1619  vwarn("%d\n",g_hash_table_size(reftab));
1620 
1621  array_list_free(refstack);
1622  g_hash_table_destroy(reftab);
1623 
1624  bsymbol_release(bsymbol);
1625 
1627 
1628  return SOAP_OK;
1629 }
1630 
1631 struct action *x_ActionSpecT_to_t_action(struct soap *soap,
1632  struct vmi1__ActionSpecT *spec,
1633  struct target *target) {
1634  struct action *action = NULL;
1635  action_type_t atype;
1636  REG reg = 0;
1637  char *ddata;
1638 
1639  atype = x_ActionTypeT_to_t_action_type_t(soap,spec->type);
1640  if (atype == ACTION_RETURN && spec->union_ActionSpecT.return_)
1641  action = action_return(spec->union_ActionSpecT.return_->code);
1642  else if (atype == ACTION_REGMOD && spec->union_ActionSpecT.regmod
1643  && spec->union_ActionSpecT.regmod->registerValue
1644  && spec->union_ActionSpecT.regmod->registerValue->name) {
1645  if (target_regno(target,
1646  spec->union_ActionSpecT.regmod->registerValue->name,
1647  &reg)) {
1648  verror("bad register number in regmod action!\n");
1649  return NULL;
1650  }
1651  action = \
1652  action_regmod(reg,
1653  spec->union_ActionSpecT.regmod->registerValue->value);
1654  }
1655  else if (atype == ACTION_MEMMOD && spec->union_ActionSpecT.memmod
1656  && spec->union_ActionSpecT.memmod->data.__ptr) {
1657  ddata = calloc(1,spec->union_ActionSpecT.memmod->data.__size);
1658  memcpy(ddata,spec->union_ActionSpecT.memmod->data.__ptr,
1659  spec->union_ActionSpecT.memmod->data.__size);
1660  action = \
1661  action_memmod(spec->union_ActionSpecT.memmod->addr,ddata,
1662  spec->union_ActionSpecT.memmod->data.__size);
1663  }
1664  else if (atype == ACTION_SINGLESTEP && spec->union_ActionSpecT.singlestep) {
1665  action = action_singlestep(spec->union_ActionSpecT.singlestep->stepCount);
1666  }
1667  else {
1668  verror("bad action spec -- could not attempt action creation!!\n");
1669  return NULL;
1670  }
1671 
1672  if (!action)
1673  verror("bad action spec -- failure in action creation!\n");
1674 
1675  return action;
1676 }
1677 
1679  GHashTable *reftab;
1680  struct vmi1__ActionEventT event;
1683 };
1684 
1685 static int _action_generic_rpc_listener_notifier(struct generic_rpc_listener *l,
1686  int is_owner,void *data) {
1687  result_t retval;
1688  struct target_rpc_listener_action_data *lad = \
1689  (struct target_rpc_listener_action_data *)data;
1690  int rc;
1691 
1692  /*
1693  * This stinks... but if we were the first
1694  */
1695 
1696  rc = soap_call_vmi1__ActionEventNotification(&l->soap,l->url,NULL,
1697  &lad->event,&lad->aer);
1698  if (rc != SOAP_OK) {
1699  if (l->soap.error == SOAP_EOF && l->soap.errnum == 0) {
1700  vwarn("timeout notifying %s; removing!",l->url);
1701  }
1702  else {
1703  verrorc("ActionEvent client call failure %s : ",
1704  l->url);
1705  soap_print_fault(&l->soap,stderr);
1706  }
1707  /* Let generic_rpc do this... */
1708  //soap_closesock(&lad->soap);
1709  return -1;
1710  }
1711 
1712  /*
1713  * (old) This is a bit crazy at the moment: if we have more than
1714  * one listener, let them all fight for the handler outcome.
1715  * Eventually, we have to restrict the outcome to only the
1716  * RPC client that created the probe, or something.
1717  *
1718  * Ok, now we know the owner; only take their response as
1719  * authoritative.
1720  */
1721  retval = x_ResultT_to_t_result_t(&l->soap,lad->aer.result);
1722  if (is_owner) {
1723  //if (retval > lad->retval)
1724  lad->retval = retval;
1725 
1726  vdebug(5,LA_XML,LF_RPC,
1727  "notified authoritative listener %s (which returned %d)\n",
1728  l->url,retval);
1729  }
1730  else {
1731  vdebug(5,LA_XML,LF_RPC,
1732  "notified non-authoritative listener %s (which returned %d)\n",
1733  l->url,retval);
1734  }
1735 
1736  if (!l->soap.keep_alive)
1737  soap_closesock(&l->soap);
1738  /*
1739  * Clean up temp/serialization data, but don't kill the sock if we
1740  * can avoid it.
1741  */
1742  soap_destroy(&l->soap);
1743  soap_end(&l->soap);
1744  //soap_done(&l->soap);
1745 
1746  return 0;
1747 }
1748 
1750  struct target_thread *thread,
1751  struct probe *probe,
1752  struct probepoint *probepoint,
1753  handler_msg_t msg,int msg_detail,
1754  void *handler_data) {
1755  struct target *target = thread->target;
1757  struct soap encoder;
1758 
1759  if (!target) {
1760  verror("probe not associated with target!\n");
1761  return RESULT_ERROR;
1762  }
1763 
1764  /*
1765  * Don't go to any effort if we don't need to...
1766  */
1768  return RESULT_SUCCESS;
1769 
1770  memset(&lad,0,sizeof(lad));
1771  lad.retval = RESULT_SUCCESS;
1772 
1774 
1775  /*
1776  * We only want to build the gsoap data struct once -- so we have to
1777  * set up a temp soap struct to do that on. We can't use the
1778  * per-listener soap struct yet cause we don't have it until we're
1779  * in the iterator above.
1780  */
1781  soap_init(&encoder);
1782  lad.reftab = g_hash_table_new_full(g_direct_hash,g_direct_equal,NULL,NULL);
1783 
1784  t_action_to_x_ActionEventT(&encoder,action,thread,msg,msg_detail,
1785  lad.reftab,&lad.event);
1786 
1788  _action_generic_rpc_listener_notifier,
1789  &lad);
1790  /*
1791  * Clean up temp/serialization data, but don't kill the sock if we
1792  * can avoid it.
1793  */
1794  g_hash_table_destroy(lad.reftab);
1795  soap_destroy(&encoder);
1796  soap_end(&encoder);
1797  soap_done(&encoder);
1798 
1800 
1801  return lad.retval;
1802 }
1803 
1805  GHashTable *reftab;
1806  struct target *target;
1807  struct probe *probe;
1808  struct vmi1__ProbeEventT event;
1811 };
1812 
1813 static int _probe_generic_rpc_listener_notifier(struct generic_rpc_listener *l,
1814  int is_owner,void *data) {
1815  result_t retval;
1816  struct target_rpc_listener_probe_data *lpd = \
1817  (struct target_rpc_listener_probe_data *)data;
1818  int rc;
1819  int i;
1820  struct action *action;
1821  action_whence_t aw;
1822 
1823  rc = soap_call_vmi1__ProbeEventNotification(&l->soap,l->url,NULL,
1824  &lpd->event,&lpd->per);
1825  if (rc != SOAP_OK) {
1826  if (l->soap.error == SOAP_EOF && l->soap.errnum == 0) {
1827  vwarn("timeout notifying %s; removing!",l->url);
1828  }
1829  else {
1830  verrorc("ProbeEvent client call failure %s : ",l->url);
1831  soap_print_fault(&l->soap,stderr);
1832  }
1833  return -1;
1834  }
1835 
1836  retval = x_ResultT_to_t_result_t(&l->soap,lpd->per.result);
1837  if (is_owner) {
1838  //if (retval > lpd->retval)
1839  lpd->retval = retval;
1840 
1841  vdebug(5,LA_XML,LF_RPC,
1842  "notified authoritative listener %s (which returned %d)\n",
1843  l->url,retval);
1844  }
1845  else {
1846  vdebug(5,LA_XML,LF_RPC,
1847  "notified non-authoritative listener %s (which returned %d)\n",
1848  l->url,retval);
1849  }
1850 
1851  if (!l->soap.keep_alive)
1852  soap_closesock(&l->soap);
1853 
1854  if (is_owner && retval == RESULT_SUCCESS) {
1855  for (i = 0; i < lpd->per.actionSpecs.__sizeactionSpec; ++i) {
1856  /*
1857  * Create the new action.
1858  */
1859  action = \
1861  &lpd->per.actionSpecs.actionSpec[i],
1862  lpd->target);
1863  if (!action) {
1864  verror("bad ActionSpec in probe response!\n");
1865  continue;
1866  }
1867 
1868  aw = x_ActionWhenceT_to_t_action_whence_t(&l->soap,lpd->per.actionSpecs.actionSpec[i].whence);
1869  if (action_sched(lpd->probe,action,aw,
1871  verror("could not schedule action!\n");
1872  }
1873  action_release(action);
1874  }
1875  }
1876  else if (lpd->per.actionSpecs.__sizeactionSpec > 0) {
1877  vwarn("non-authoritative listener %s tried to send %d actions!\n",
1878  l->url,lpd->per.actionSpecs.__sizeactionSpec);
1879  }
1880 
1881  soap_destroy(&l->soap);
1882  soap_end(&l->soap);
1883  //soap_done(&l->soap);
1884 
1885  return 0;
1886 }
1887 
1889  void *handler_data,struct probe *trigger,
1890  struct probe *base) {
1891  struct target *target = probe->target;
1892  struct target_rpc_listener_probe_data lpd;
1893  struct soap encoder;
1894 
1895  if (!target) {
1896  verror("probe not associated with target!\n");
1897  return RESULT_ERROR;
1898  }
1899 
1900  /*
1901  * Don't go to any effort if we don't need to...
1902  */
1904  return RESULT_SUCCESS;
1905 
1906  memset(&lpd,0,sizeof(lpd));
1907  lpd.retval = RESULT_SUCCESS;
1908 
1910 
1911  /*
1912  * We only want to build the gsoap data struct once -- so we have to
1913  * set up a temp soap struct to do that on. We can't use the
1914  * per-listener soap struct yet cause we don't have it until we're
1915  * in the iterator above.
1916  */
1917  soap_init(&encoder);
1918 
1919  lpd.reftab = g_hash_table_new_full(g_direct_hash,g_direct_equal,NULL,NULL);
1920  lpd.target = target;
1921  lpd.probe = probe;
1922  t_probe_to_x_ProbeEventT(&encoder,probe,tid,type,trigger,base,lpd.reftab,&lpd.event);
1923 
1925  _probe_generic_rpc_listener_notifier,
1926  &lpd);
1927 
1928  g_hash_table_destroy(lpd.reftab);
1929  soap_destroy(&encoder);
1930  soap_end(&encoder);
1931  soap_done(&encoder);
1932 
1934 
1935  return lpd.retval;
1936 };
1937 
1939  void *handler_data,
1940  struct probe *trigger,struct probe *base) {
1941  return _target_rpc_probe_handler(0,probe,tid,handler_data,trigger,base);
1942 };
1943 
1944 
1946  void *handler_data,
1947  struct probe *trigger,struct probe *base) {
1948  return _target_rpc_probe_handler(1,probe,tid,handler_data,trigger,base);
1949 };
1950 
1951 int vmi1__ProbeSymbolSimple(struct soap *soap,
1952  vmi1__TargetIdT tid,vmi1__ThreadIdT thid,
1953  char *probeName,char *symbol,
1954  struct vmi1__ProbeResponse *r) {
1955  struct target *t = NULL;
1956  struct probe *p;
1957  target_status_t status;
1958  GHashTable *reftab;
1959  int did_pause = 0;
1960 
1962  (void **)&t,NULL)) {
1963  return soap_receiver_fault(soap,"Nonexistent target!",
1964  "Specified target does not exist!");
1965  }
1966 
1967  PROXY_REQUEST_LOCKED(soap,tid,&target_rpc_mutex);
1968 
1969  if (thid == -1)
1970  thid = TID_GLOBAL;
1971 
1972  if ((status = target_status(t)) != TSTATUS_PAUSED) {
1973  if (target_pause(t)) {
1975  return soap_receiver_fault(soap,"Could not pause target!",
1976  "Could not pause target before adding probe!");
1977  }
1978  did_pause = 1;
1979  }
1980 
1981  vdebug(9,LA_XML,LF_RPC,"target status %d\n",status);
1982 
1983  p = probe_simple(t,thid,symbol,_target_rpc_probe_prehandler,
1985  if (!p) {
1986  verror("could not add a probe on symbol '%s' in target %d thread %d\n",
1987  symbol,tid,thid);
1988  if (did_pause)
1989  target_resume(t);
1991  return soap_receiver_fault(soap,"Could not add probe!",
1992  "Could not add probe!");
1993  }
1994 
1995  probe_rename(p,probeName);
1996 
1997  if (did_pause) {
1998  if (target_resume(t)) {
2000  return soap_receiver_fault(soap,"Could not resume target, but probe added successfully!",
2001  "Could not resume target after adding probe!");
2002  }
2003  }
2004 
2005  reftab = g_hash_table_new_full(g_direct_hash,g_direct_equal,NULL,NULL);
2006  r->probe = t_probe_to_x_ProbeT(soap,p,reftab,NULL);
2007  g_hash_table_destroy(reftab);
2008 
2010 
2011  return SOAP_OK;
2012 }
2013 
2014 int vmi1__ProbeSymbol(struct soap *soap,
2015  vmi1__TargetIdT tid,vmi1__ThreadIdT thid,
2016  char *probeName,char *symbol,
2017  vmi1__ProbepointStyleT *probepointStyle,
2018  vmi1__ProbepointWhenceT *probepointWhence,
2019  vmi1__ProbepointSizeT *probepointSize,
2020  struct vmi1__ProbeResponse *r) {
2021  struct target *t = NULL;
2023  struct bsymbol *bsymbol;
2024  GHashTable *reftab;
2025  struct probe *probe;
2029 
2031  (void **)&t,NULL)) {
2032  return soap_receiver_fault(soap,"Nonexistent target!",
2033  "Specified target does not exist!");
2034  }
2035 
2036  PROXY_REQUEST_LOCKED(soap,tid,&target_rpc_mutex);
2037 
2038  if (thid == -1)
2039  thid = TID_GLOBAL;
2040 
2041  if ((status = target_status(t)) != TSTATUS_PAUSED) {
2042  if (target_pause(t)) {
2044  return soap_receiver_fault(soap,"Could not pause target!",
2045  "Could not pause target before adding probe!");
2046  }
2047  }
2048  vdebug(9,LA_XML,LF_RPC,"target status %d\n",status);
2049 
2050  bsymbol = target_lookup_sym(t,symbol,NULL,NULL,SYMBOL_TYPE_NONE);
2051 
2052  if (!bsymbol) {
2054  return soap_receiver_fault(soap,"Could not find symbol!",
2055  "Could not find symbol!");
2056  }
2057 
2058  probe = probe_create(t,tid,NULL,probeName,_target_rpc_probe_prehandler,
2060  if (!probe) {
2062  return soap_receiver_fault(soap,"Could not create probe!",
2063  "Could not create probe!");
2064  }
2065 
2066  if (probepointStyle)
2067  ppstyle = x_ProbepointStyleT_to_t_probepoint_style_t(soap,*probepointStyle);
2068  if (probepointWhence)
2069  ppwhence = x_ProbepointWhenceT_to_t_probepoint_whence_t(soap,*probepointWhence);
2070  if (probepointSize)
2071  ppsize = x_ProbepointSizeT_to_t_probepoint_watchsize_t(soap,*probepointSize);
2072 
2073  if (probe_register_symbol(probe,bsymbol,ppstyle,ppwhence,ppsize)) {
2074  probe_free(probe,1);
2075  bsymbol_release(bsymbol);
2077  return soap_receiver_fault(soap,"Could not register probe!",
2078  "Could not register probe!");
2079  }
2080 
2081  bsymbol_release(bsymbol);
2082 
2083  if (status != TSTATUS_PAUSED) {
2084  if (target_resume(t)) {
2086  return soap_receiver_fault(soap,"Could not resume target!",
2087  "Could not resume target after adding probe!");
2088  }
2089  }
2090 
2091  reftab = g_hash_table_new_full(g_direct_hash,g_direct_equal,NULL,NULL);
2092  r->probe = t_probe_to_x_ProbeT(soap,probe,reftab,NULL);
2093  g_hash_table_destroy(reftab);
2094 
2096 
2097  return SOAP_OK;
2098 }
2099 
2100 int vmi1__ProbeAddr(struct soap *soap,
2101  vmi1__TargetIdT tid,vmi1__ThreadIdT thid,
2102  char *probeName,vmi1__ADDR addr,
2103  vmi1__ProbepointTypeT *probepointType,
2104  vmi1__ProbepointStyleT *probepointStyle,
2105  vmi1__ProbepointWhenceT *probepointWhence,
2106  vmi1__ProbepointSizeT *probepointSize,
2107  struct vmi1__ProbeResponse *r) {
2108  struct target *t = NULL;
2110  GHashTable *reftab;
2111  struct probe *probe;
2116 
2118  (void **)&t,NULL)) {
2119  return soap_receiver_fault(soap,"Nonexistent target!",
2120  "Specified target does not exist!");
2121  }
2122 
2123  PROXY_REQUEST_LOCKED(soap,tid,&target_rpc_mutex);
2124 
2125  if (thid == -1)
2126  thid = TID_GLOBAL;
2127 
2128  if ((status = target_status(t)) != TSTATUS_PAUSED) {
2129  if (target_pause(t)) {
2131  return soap_receiver_fault(soap,"Could not pause target!",
2132  "Could not pause target before adding probe!");
2133  }
2134  }
2135  vdebug(9,LA_XML,LF_RPC,"target status %d\n",status);
2136 
2137  probe = probe_create(t,thid,NULL,probeName,_target_rpc_probe_prehandler,
2139  if (!probe) {
2141  return soap_receiver_fault(soap,"Could not create probe!",
2142  "Could not create probe!");
2143  }
2144 
2145  if (probepointType)
2146  pptype = x_ProbepointTypeT_to_t_probepoint_type_t(soap,*probepointType);
2147  if (probepointStyle)
2148  ppstyle = x_ProbepointStyleT_to_t_probepoint_style_t(soap,*probepointStyle);
2149  if (probepointWhence)
2150  ppwhence = x_ProbepointWhenceT_to_t_probepoint_whence_t(soap,*probepointWhence);
2151  if (probepointSize)
2152  ppsize = x_ProbepointSizeT_to_t_probepoint_watchsize_t(soap,*probepointSize);
2153 
2154  if (!probe_register_addr(probe,addr,pptype,ppstyle,ppwhence,ppsize,NULL)) {
2155  probe_free(probe,1);
2157  return soap_receiver_fault(soap,"Could not register probe!",
2158  "Could not register probe!");
2159  }
2160 
2161  if (status != TSTATUS_PAUSED) {
2162  if (target_resume(t)) {
2164  return soap_receiver_fault(soap,"Could not resume target!",
2165  "Could not resume target after adding probe!");
2166  }
2167  }
2168 
2169  reftab = g_hash_table_new_full(g_direct_hash,g_direct_equal,NULL,NULL);
2170  r->probe = t_probe_to_x_ProbeT(soap,probe,reftab,NULL);
2171  g_hash_table_destroy(reftab);
2172 
2174 
2175  return SOAP_OK;
2176 }
2177 
2178 int vmi1__ProbeLine(struct soap *soap,
2179  vmi1__TargetIdT tid,vmi1__ThreadIdT thid,
2180  char *probeName,char *filename,int line,
2181  vmi1__ProbepointStyleT *probepointStyle,
2182  vmi1__ProbepointWhenceT *probepointWhence,
2183  vmi1__ProbepointSizeT *probepointSize,
2184  struct vmi1__ProbeResponse *r) {
2185  struct target *t = NULL;
2187  GHashTable *reftab;
2188  struct probe *probe;
2192 
2194  (void **)&t,NULL)) {
2195  return soap_receiver_fault(soap,"Nonexistent target!",
2196  "Specified target does not exist!");
2197  }
2198 
2199  PROXY_REQUEST_LOCKED(soap,tid,&target_rpc_mutex);
2200 
2201  if (thid == -1)
2202  thid = TID_GLOBAL;
2203 
2204  if ((status = target_status(t)) != TSTATUS_PAUSED) {
2205  if (target_pause(t)) {
2207  return soap_receiver_fault(soap,"Could not pause target!",
2208  "Could not pause target before adding probe!");
2209  }
2210  }
2211  vdebug(9,LA_XML,LF_RPC,"target status %d\n",status);
2212 
2213  probe = probe_create(t,thid,NULL,probeName,_target_rpc_probe_prehandler,
2215  if (!probe) {
2217  return soap_receiver_fault(soap,"Could not create probe!",
2218  "Could not create probe!");
2219  }
2220 
2221  if (probepointStyle)
2222  ppstyle = x_ProbepointStyleT_to_t_probepoint_style_t(soap,*probepointStyle);
2223  if (probepointWhence)
2224  ppwhence = x_ProbepointWhenceT_to_t_probepoint_whence_t(soap,*probepointWhence);
2225  if (probepointSize)
2226  ppsize = x_ProbepointSizeT_to_t_probepoint_watchsize_t(soap,*probepointSize);
2227 
2228  if (!probe_register_line(probe,filename,line,ppstyle,ppwhence,ppsize)) {
2229  probe_free(probe,1);
2231  return soap_receiver_fault(soap,"Could not register probe!",
2232  "Could not register probe!");
2233  }
2234 
2235  if (status != TSTATUS_PAUSED) {
2236  if (target_resume(t)) {
2238  return soap_receiver_fault(soap,"Could not resume target!",
2239  "Could not resume target after adding probe!");
2240  }
2241  }
2242 
2243  reftab = g_hash_table_new_full(g_direct_hash,g_direct_equal,NULL,NULL);
2244  r->probe = t_probe_to_x_ProbeT(soap,probe,reftab,NULL);
2245  g_hash_table_destroy(reftab);
2246 
2248 
2249  return SOAP_OK;
2250 }
2251 
2252 int vmi1__EnableProbe(struct soap *soap,
2253  vmi1__TargetIdT tid,vmi1__ProbeIdT pid,
2254  struct vmi1__NoneResponse *r) {
2255  struct target *t = NULL;
2257  struct probe *probe;
2258 
2260  (void **)&t,NULL)) {
2261  return soap_receiver_fault(soap,"Nonexistent target!",
2262  "Specified target does not exist!");
2263  }
2264 
2265  PROXY_REQUEST_LOCKED(soap,tid,&target_rpc_mutex);
2266 
2267  probe = target_lookup_probe(t,pid);
2268  if (!probe) {
2270  return soap_receiver_fault(soap,"Could not find probe!",
2271  "Could not find probe!");
2272  }
2273 
2274  if ((status = target_status(t)) != TSTATUS_PAUSED) {
2275  if (target_pause(t)) {
2277  return soap_receiver_fault(soap,"Could not pause target!",
2278  "Could not pause target before adding probe!");
2279  }
2280  }
2281  vdebug(9,LA_XML,LF_RPC,"target status %d\n",status);
2282 
2283  probe = target_lookup_probe(t,pid);
2284  if (!probe) {
2286  return soap_receiver_fault(soap,"Could not find probe!",
2287  "Could not find probe!");
2288  }
2289 
2290  if (probe_enable(probe)) {
2292  return soap_receiver_fault(soap,"Could not enable probe!",
2293  "Could not enable probe!");
2294  }
2295 
2296  if (status != TSTATUS_PAUSED) {
2297  if (target_resume(t)) {
2299  return soap_receiver_fault(soap,"Could not resume target!",
2300  "Could not resume target after adding probe!");
2301  }
2302  }
2303 
2305 
2306  return SOAP_OK;
2307 }
2308 
2309 int vmi1__DisableProbe(struct soap *soap,
2310  vmi1__TargetIdT tid,vmi1__ProbeIdT pid,
2311  struct vmi1__NoneResponse *r) {
2312  struct target *t = NULL;
2314  struct probe *probe;
2315 
2317  (void **)&t,NULL)) {
2318  return soap_receiver_fault(soap,"Nonexistent target!",
2319  "Specified target does not exist!");
2320  }
2321 
2322  PROXY_REQUEST_LOCKED(soap,tid,&target_rpc_mutex);
2323 
2324  probe = target_lookup_probe(t,pid);
2325  if (!probe) {
2327  return soap_receiver_fault(soap,"Could not find probe!",
2328  "Could not find probe!");
2329  }
2330 
2331  if ((status = target_status(t)) != TSTATUS_PAUSED) {
2332  if (target_pause(t)) {
2334  return soap_receiver_fault(soap,"Could not pause target!",
2335  "Could not pause target before adding probe!");
2336  }
2337  }
2338  vdebug(9,LA_XML,LF_RPC,"target status %d\n",status);
2339 
2340  probe = target_lookup_probe(t,pid);
2341  if (!probe) {
2343  return soap_receiver_fault(soap,"Could not find probe!",
2344  "Could not find probe!");
2345  }
2346 
2347  if (probe_disable(probe)) {
2349  return soap_receiver_fault(soap,"Could not disable probe!",
2350  "Could not disable probe!");
2351  }
2352 
2353  if (status != TSTATUS_PAUSED) {
2354  if (target_resume(t)) {
2356  return soap_receiver_fault(soap,"Could not resume target!",
2357  "Could not resume target after adding probe!");
2358  }
2359  }
2360 
2362 
2363  return SOAP_OK;
2364 }
2365 
2366 int vmi1__RemoveProbe(struct soap *soap,
2367  vmi1__TargetIdT tid,vmi1__ProbeIdT pid,
2368  struct vmi1__NoneResponse *r) {
2369  struct target *t = NULL;
2371  struct probe *probe;
2372 
2374  (void **)&t,NULL)) {
2375  return soap_receiver_fault(soap,"Nonexistent target!",
2376  "Specified target does not exist!");
2377  }
2378 
2379  PROXY_REQUEST_LOCKED(soap,tid,&target_rpc_mutex);
2380 
2381  probe = target_lookup_probe(t,pid);
2382  if (!probe) {
2384  return soap_receiver_fault(soap,"Could not find probe!",
2385  "Could not find probe!");
2386  }
2387 
2388  if ((status = target_status(t)) != TSTATUS_PAUSED) {
2389  if (target_pause(t)) {
2391  return soap_receiver_fault(soap,"Could not pause target!",
2392  "Could not pause target before adding probe!");
2393  }
2394  }
2395  vdebug(9,LA_XML,LF_RPC,"target status %d\n",status);
2396 
2397  probe = target_lookup_probe(t,pid);
2398  if (!probe) {
2400  return soap_receiver_fault(soap,"Could not find probe!",
2401  "Could not find probe!");
2402  }
2403 
2404  if (probe_free(probe,1)) {
2406  return soap_receiver_fault(soap,"Could not remove probe!",
2407  "Could not remove probe!");
2408  }
2409 
2410  if (status != TSTATUS_PAUSED) {
2411  if (target_resume(t)) {
2413  return soap_receiver_fault(soap,"Could not resume target!",
2414  "Could not resume target after adding probe!");
2415  }
2416  }
2417 
2419 
2420  return SOAP_OK;
2421 }
2422 
2423 int vmi1__TargetBindListener(struct soap *soap,
2424  vmi1__TargetIdT tid,vmi1__ListenerT *listener,
2425  struct vmi1__NoneResponse *r) {
2426  char *url;
2427  int len = 0;
2428  struct target *t = NULL;
2429 
2430  if (!listener)
2431  return soap_receiver_fault(soap,"Bad listener!","Bad listener!");
2432  else if (listener->url != NULL)
2433  url = listener->url;
2434  else if (listener->hostname != NULL && listener->port != NULL) {
2435  len = sizeof("http://") + strlen(listener->hostname) \
2436  + sizeof(":") + 11 + sizeof(":/vmi/1/targetListener") + 1;
2437  url = malloc(len * sizeof(char));
2438  sprintf(url,"http://%s:%d/vmi/1/targetListener",
2439  listener->hostname,*listener->port);
2440  }
2441  else {
2442  return soap_receiver_fault(soap,"Bad listener!","Bad listener!");
2443  }
2444 
2446  (void **)&t,NULL)) {
2447  if (len)
2448  free(url);
2449  return soap_receiver_fault(soap,"Nonexistent target!",
2450  "Specified target does not exist!");
2451  }
2452 
2453  PROXY_REQUEST_LOCKED(soap,tid,&target_rpc_mutex);
2454 
2456  if (len)
2457  free(url);
2458  return soap_receiver_fault(soap,"Could not bind to target!",
2459  "Could not bind to target!");
2460  }
2461 
2463 
2464  return SOAP_OK;
2465 }
2466 
2467 int vmi1__TargetUnbindListener(struct soap *soap,
2468  vmi1__TargetIdT tid,vmi1__ListenerT *listener,
2469  struct vmi1__NoneResponse *r) {
2470  char *url;
2471  int len = 0;
2472  struct target *t = NULL;
2473 
2474  if (!listener)
2475  return soap_receiver_fault(soap,"Bad listener!","Bad listener!");
2476  else if (listener->url != NULL)
2477  url = listener->url;
2478  else if (listener->hostname != NULL && listener->port != NULL) {
2479  len = sizeof("http://") + strlen(listener->hostname) \
2480  + sizeof(":") + 11 + sizeof(":/vmi/1/targetListener") + 1;
2481  url = malloc(len * sizeof(char));
2482  sprintf(url,"http://%s:%d/vmi/1/targetListener",
2483  listener->hostname,*listener->port);
2484  }
2485  else {
2486  return soap_receiver_fault(soap,"Bad listener!","Bad listener!");
2487  }
2488 
2490  (void **)&t,NULL)) {
2491  if (len)
2492  free(url);
2493  return soap_receiver_fault(soap,"Nonexistent target!",
2494  "Specified target does not exist!");
2495  }
2496 
2497  PROXY_REQUEST_LOCKED(soap,tid,&target_rpc_mutex);
2498 
2500  if (len)
2501  free(url);
2502  return soap_receiver_fault(soap,"Could not unbind from target!",
2503  "Could not unbind from target!");
2504  }
2505 
2507 
2508  return SOAP_OK;
2509 }
2510 
2521 /*
2522 int vmi1__RegisterTargetListener(struct soap *soap,
2523  char *host,int port,enum xsd__boolean ssl,
2524  struct vmi1__ListenerIdResponse *r) {
2525  int listener_id;
2526  char urlbuf[SOAP_TAGLEN];
2527 
2528  snprintf(urlbuf,sizeof(urlbuf),
2529  "http://%s:%d/vmi/1/targetListener",host,port);
2530 
2531  listener_id = generic_rpc_insert_listener(RPC_SVCTYPE_TARGET,urlbuf);
2532  if (listener_id < 0)
2533  return soap_receiver_fault(soap,"Could not register listener!",
2534  "Could not register listener!");
2535 
2536  r->listenerId = listener_id;
2537 
2538  return SOAP_OK;
2539 }
2540 
2541 int vmi1__RegisterTargetListenerURL(struct soap *soap,
2542  char *url,enum xsd__boolean ssl,
2543  struct vmi1__ListenerIdResponse *r) {
2544  int listener_id;
2545 
2546  if ((listener_id = generic_rpc_insert_listener(RPC_SVCTYPE_TARGET,url)) < 0)
2547  return soap_receiver_fault(soap,"Could not register listener!",
2548  "Could not register listener!");
2549 
2550  r->listenerId = listener_id;
2551 
2552  return SOAP_OK;
2553 }
2554 
2555 int vmi1__UnregisterTargetListener(struct soap *soap,
2556  vmi1__ListenerIdT listenerId,
2557  struct vmi1__NoneResponse *r) {
2558  if (generic_rpc_remove_listener(RPC_SVCTYPE_TARGET,listenerId))
2559  return soap_receiver_fault(soap,"Could not remove listener!",
2560  "Could not remove listener!");
2561 
2562  return SOAP_OK;
2563 }
2564 */
struct target * target_instantiate_overlay(struct target *target, tid_t tid, struct target_spec *spec)
Definition: target_api.c:757
struct vmi1__TargetEventT event
Definition: target_rpc.c:150
void target_rpc_fini(void)
Definition: target_rpc.c:416
target_event_t
Definition: target_event.h:28
struct vmi1__DebugFileOptsT defDebugFileOpts
Definition: debuginfo_rpc.c:45
int monitor_del_objid(struct monitor *monitor, int objid)
Definition: monitor.c:788
int proxyreq_recv_request(struct monitor *monitor, struct monitor_msg *msg)
Definition: proxyreq.c:552
struct action * action_return(REGVAL retval)
Definition: probe.c:4457
int vmi1__GetTarget(struct soap *soap, vmi1__TargetIdT tid, struct vmi1__TargetResponse *r)
Definition: target_rpc.c:520
struct bsymbol * target_lookup_sym_line(struct target *target, char *filename, int line, SMOFFSET *offset, ADDR *addr)
Definition: target.c:2267
int monitor_add_primary_obj(struct monitor *monitor, int objid, int objtype, void *obj, void *objstate)
Definition: monitor.c:1576
int vmi1__ProbeSymbol(struct soap *soap, vmi1__TargetIdT tid, vmi1__ThreadIdT thid, char *probeName, char *symbol, vmi1__ProbepointStyleT *probepointStyle, vmi1__ProbepointWhenceT *probepointWhence, vmi1__ProbepointSizeT *probepointSize, struct vmi1__ProbeResponse *r)
Definition: target_rpc.c:2014
void * obj
Definition: monitor.h:244
int monitor_lookup_objid_lock_objtype(int objid, int objtype, void **obj, struct monitor **monitor)
Definition: monitor.c:350
struct vmi1__TargetT * t_target_to_x_TargetT(struct soap *soap, struct target *target, GHashTable *reftab, struct vmi1__TargetT *out)
Definition: target_xml.c:1004
struct lsymbol * lsymbol
Definition: target.h:1017
int32_t tid_t
Definition: common.h:36
#define SOAP_CALLOC(soap, nmemb, size)
Definition: util.h:25
probepoint_type_t
Definition: probe_api.h:213
int monitor_register_objtype(int objtype, struct monitor_objtype_ops *ops, pthread_mutex_t *objtype_mutex)
Definition: monitor.c:1052
target_status_t
Definition: target_api.h:197
int target_load_available_threads(struct target *target, int force)
Definition: target_api.c:1300
int generic_rpc_unbind_dynlistener_objid(rpc_svctype_t svctype, char *listener_url, int objid)
Definition: generic_rpc.c:864
struct symbol * symbol
Definition: dwdebug.h:1010
action_whence_t
Definition: probe_api.h:257
Definition: probe.h:392
int vmi1__ProbeSymbolSimple(struct soap *soap, vmi1__TargetIdT tid, vmi1__ThreadIdT thid, char *probeName, char *symbol, struct vmi1__ProbeResponse *r)
Definition: target_rpc.c:1951
int monitor_get_unique_objid(void)
Definition: monitor.c:161
void * p
int target_rpc_handle_request(struct soap *soap)
Definition: target_rpc.c:465
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 objid
Definition: monitor.h:335
struct monitor * monitor
void target_init(void)
Definition: target.c:69
char * msg
Definition: monitor.h:352
void generic_rpc_init(void)
Definition: generic_rpc.c:69
REFCNT action_release(struct action *action)
Definition: probe.c:4576
REGVAL retval
Definition: probe.h:411
int target_resume(struct target *target)
Definition: target_api.c:1012
int monitor_add_obj(struct monitor *monitor, int objid, int objtype, void *obj, void *objstate)
Definition: monitor.c:554
int vmi1__PauseTarget(struct soap *soap, vmi1__TargetIdT tid, struct vmi1__NoneResponse *r)
Definition: target_rpc.c:1183
int target_is_evloop_attached(struct target *target, struct evloop *evloop)
Definition: target_api.c:863
probepoint_whence_t
Definition: probe_api.h:234
int vmi1__CloseTarget(struct soap *soap, vmi1__TargetIdT tid, struct vmi1__NoneResponse *r)
Definition: target_rpc.c:1231
uint8_t kill_on_close
Definition: target_api.h:2213
int vmi1__TargetBindListener(struct soap *soap, vmi1__TargetIdT tid, vmi1__ListenerT *listener, struct vmi1__NoneResponse *r)
Definition: target_rpc.c:2423
int vmi1__LookupTargetAddrSimple(struct soap *soap, vmi1__TargetIdT tid, vmi1__ADDR addr, struct vmi1__DebugFileOptsT *opts, struct vmi1__SymbolResponse *r)
Definition: target_rpc.c:1430
char * GENERIC_RPC_TMPDIR
Definition: generic_rpc.c:52
int generic_rpc_unbind_all_listeners_objid(rpc_svctype_t svctype, int objid)
Definition: generic_rpc.c:733
int monitor_setup_stderr(struct monitor *monitor, int maxbufsiz, char *stderr_logfile, monitor_stdio_callback_t stderr_callback, void *callback_state)
Definition: monitor.c:1897
struct xsd__hexBinary * stderrLog
int target_pause(struct target *target)
Definition: target_api.c:1027
int target_pause_thread(struct target *target, tid_t tid, int nowait)
Definition: target_api.c:1323
result_t _target_rpc_probe_handler(int type, struct probe *probe, tid_t tid, void *handler_data, struct probe *trigger, struct probe *base)
Definition: target_rpc.c:1888
struct evloop * evloop
Definition: monitor.h:256
int vmi1__LookupTargetSymbolSimple(struct soap *soap, vmi1__TargetIdT tid, char *name, struct vmi1__DebugFileOptsT *opts, struct vmi1__SymbolResponse *r)
Definition: target_rpc.c:1330
struct vmi1__ActionEventT event
Definition: target_rpc.c:1680
struct soap * soap
Definition: proxyreq.h:160
int target_close(struct target *target)
Definition: target_api.c:1511
struct list_head probe
Definition: probe.h:379
#define verror(format,...)
Definition: log.h:30
struct vmi1__ProbeT * probe
struct probe * probe_register_addr(struct probe *probe, ADDR addr, probepoint_type_t type, probepoint_style_t style, probepoint_whence_t whence, probepoint_watchsize_t watchsize, struct bsymbol *bsymbol)
Definition: probe.c:1393
#define verrorc(format,...)
Definition: log.h:32
int target_regno(struct target *target, char *name, REG *reg)
Definition: target_api.c:1120
struct action * action_memmod(ADDR dest, char *data, uint32_t len)
Definition: probe.c:4553
Definition: evloop.h:66
void target_fini(void)
Definition: target.c:91
enum _vmi1__targetEventType t_target_event_t_to_x_targetEventType(target_event_t chtype)
Definition: target_rpc.c:214
void target_rpc_init(void)
Definition: target_rpc.c:393
int proxyreq_attach_new_objid(struct proxyreq *pr, int objid, struct monitor *monitor)
Definition: proxyreq.c:421
int vmi1__RemoveProbe(struct soap *soap, vmi1__TargetIdT tid, vmi1__ProbeIdT pid, struct vmi1__NoneResponse *r)
Definition: target_rpc.c:2366
#define vwarn(format,...)
Definition: log.h:33
result_t x_ResultT_to_t_result_t(struct soap *soap, enum vmi1__ResultT in)
Definition: common_xml.c:24
struct vmi1__TargetEventNotificationResponse ter
Definition: target_rpc.c:151
void free(void *ptr)
Definition: debugserver.c:207
action_whence_t x_ActionWhenceT_to_t_action_whence_t(struct soap *soap, enum vmi1__ActionWhenceT in)
Definition: target_xml.c:1527
result_t _target_rpc_probe_prehandler(struct probe *probe, tid_t tid, void *handler_data, struct probe *trigger, struct probe *base)
Definition: target_rpc.c:1938
struct target_spec * x_TargetSpecT_to_t_target_spec(struct soap *soap, struct vmi1__TargetSpecT *spec, GHashTable *reftab, struct target_spec *out)
Definition: target_xml.c:206
int vmi1__LookupTargetAddr(struct soap *soap, vmi1__TargetIdT tid, vmi1__ADDR addr, struct vmi1__DebugFileOptsT *opts, struct vmi1__NestedSymbolResponse *r)
Definition: target_rpc.c:1477
struct vmi1__ActionSpecsT actionSpecs
struct vmi1__TargetT * target
tid_t tid
Definition: probe.h:344
int target_attach_evloop(struct target *target, struct evloop *evloop)
Definition: target_api.c:834
int vmi1__EnableProbe(struct soap *soap, vmi1__TargetIdT tid, vmi1__ProbeIdT pid, struct vmi1__NoneResponse *r)
Definition: target_rpc.c:2252
int monitor_lock_objtype(int objtype)
Definition: monitor.c:243
unsigned char * __ptr
Definition: xsdc.gsm.h:13
#define array_list_foreach(alist, lpc, placeholder)
Definition: alist.h:371
struct action * action_regmod(REG regnum, REGVAL regval)
Definition: probe.c:4532
struct soap soap
Definition: generic_rpc.h:97
REFCNT bsymbol_release(struct bsymbol *bsymbol)
Definition: symbol.c:90
monitor_event_t
Definition: monitor.h:62
struct vmi1__ProbeEventT * t_probe_to_x_ProbeEventT(struct soap *soap, struct probe *probe, tid_t tid, int type, struct probe *trigger, struct probe *base, GHashTable *reftab, struct vmi1__ProbeEventT *out)
Definition: target_xml.c:1304
struct probe * target_lookup_probe(struct target *target, int probe_id)
Definition: target_api.c:1666
probepoint_watchsize_t
Definition: probe_api.h:241
int probe_free(struct probe *probe, int force)
Definition: probe.c:777
short cmd
Definition: monitor.h:349
struct dt_argp_state opts
Definition: dumptarget.c:111
int vmi1__InstantiateOverlayTarget(struct soap *soap, vmi1__TargetIdT utid, vmi1__ThreadIdT thid, struct vmi1__TargetSpecT *spec, vmi1__ListenerT *ownerListener, struct vmi1__TargetResponse *r)
Definition: target_rpc.c:1028
void target_free_spec(struct target_spec *spec)
Definition: target_api.c:453
int target_spec_to_argv(struct target_spec *spec, char *arg0, int *argc, char ***argv)
Definition: target.c:416
int monitor_close_obj(struct monitor *monitor, void *obj, int kill, int kill_sig)
Definition: monitor.c:622
struct vmi1__SymbolT * d_symbol_to_x_SymbolT(struct soap *soap, struct symbol *s, struct vmi1__DebugFileOptsT *opts, GHashTable *reftab, struct array_list *refstack, int depth)
int monitor_del_obj(struct monitor *monitor, void *obj)
Definition: monitor.c:763
struct xsd__hexBinary * stdoutLog
Definition: log.h:203
int monitor_unlock_objtype_unsafe(int objtype)
Definition: monitor.c:275
result_t _target_rpc_action_handler(struct action *action, struct target_thread *thread, struct probe *probe, struct probepoint *probepoint, handler_msg_t msg, int msg_detail, void *handler_data)
Definition: target_rpc.c:1749
void monitor_fini(void)
Definition: monitor.c:127
struct action * action_singlestep(int nsteps)
Definition: probe.c:4483
int vmi1__LookupTargetLine(struct soap *soap, vmi1__TargetIdT tid, char *filename, int line, struct vmi1__DebugFileOptsT *opts, struct vmi1__NestedSymbolResponse *r)
Definition: target_rpc.c:1578
probepoint_whence_t x_ProbepointWhenceT_to_t_probepoint_whence_t(struct soap *soap, enum vmi1__ProbepointWhenceT in)
Definition: target_xml.c:1418
probepoint_watchsize_t x_ProbepointSizeT_to_t_probepoint_watchsize_t(struct soap *soap, enum vmi1__ProbepointSizeT in)
Definition: target_xml.c:1453
int probe_enable(struct probe *probe)
Definition: probe.c:1861
struct bsymbol * target_lookup_sym_addr(struct target *target, ADDR addr)
Definition: target.c:2093
probepoint_style_t x_ProbepointStyleT_to_t_probepoint_style_t(struct soap *soap, enum vmi1__ProbepointStyleT in)
Definition: target_xml.c:1387
int len
Definition: dumptarget.c:52
struct vmi1__ActionEventNotificationResponse aer
Definition: target_rpc.c:1681
int vmi1__PauseThread(struct soap *soap, vmi1__TargetIdT tid, vmi1__ThreadIdT thid, struct vmi1__NoneResponse *r)
Definition: target_rpc.c:1306
struct vmi1__ActionEventT * t_action_to_x_ActionEventT(struct soap *soap, struct action *action, struct target_thread *tthread, handler_msg_t msg, int msg_detail, GHashTable *reftab, struct vmi1__ActionEventT *out)
Definition: target_xml.c:1667
void debuginfo_rpc_fini(void)
Definition: debuginfo_rpc.c:69
Definition: probe.h:308
void generic_rpc_register_svctype(rpc_svctype_t svctype)
Definition: generic_rpc.c:139
int monitor_setup_stdin(struct monitor *monitor, char *stdin_buf, int stdin_buflen)
Definition: monitor.c:1817
struct probe * probe_create(struct target *target, tid_t tid, struct probe_ops *pops, const char *name, probe_handler_t pre_handler, probe_handler_t post_handler, void *handler_data, int autofree, int tracked)
Definition: probe.c:729
int generic_rpc_bind_dynlistener_objid(rpc_svctype_t svctype, char *listener_url, int objid, int owns)
Definition: generic_rpc.c:804
int vmi1__TargetUnbindListener(struct soap *soap, vmi1__TargetIdT tid, vmi1__ListenerT *listener, struct vmi1__NoneResponse *r)
Definition: target_rpc.c:2467
#define vdebug(devel, areas, flags, format,...)
Definition: log.h:302
struct vmi1__SymbolsT * nestedSymbol
struct action * x_ActionSpecT_to_t_action(struct soap *soap, struct vmi1__ActionSpecT *spec, struct target *target)
Definition: target_rpc.c:1631
void debuginfo_rpc_init(void)
Definition: debuginfo_rpc.c:53
int vmi1__ProbeLine(struct soap *soap, vmi1__TargetIdT tid, vmi1__ThreadIdT thid, char *probeName, char *filename, int line, vmi1__ProbepointStyleT *probepointStyle, vmi1__ProbepointWhenceT *probepointWhence, vmi1__ProbepointSizeT *probepointSize, struct vmi1__ProbeResponse *r)
Definition: target_rpc.c:2178
struct vmi1__ProbeEventNotificationResponse per
Definition: target_rpc.c:1809
probepoint_type_t x_ProbepointTypeT_to_t_probepoint_type_t(struct soap *soap, enum vmi1__ProbepointTypeT in)
Definition: target_xml.c:1360
short seqno
Definition: monitor.h:350
handler_msg_t
Definition: probe_api.h:52
int vmi1__GetTargetLogs(struct soap *soap, vmi1__TargetIdT tid, int maxSize, struct vmi1__TargetLogsResponse *r)
Definition: target_rpc.c:543
int target_detach_evloop(struct target *target)
Definition: target_api.c:846
Definition: log.h:72
struct vmi1__TargetT ** target
struct vmi1__TargetT * t_target_id_to_x_TargetT(struct soap *soap, int target_id, struct target_spec *spec, GHashTable *reftab, struct vmi1__TargetT *out)
Definition: target_xml.c:946
void * calloc(size_t nmemb, size_t size)
Definition: debugserver.c:200
struct array_list * monitor_list_objids_by_objtype_lock_objtype(int objtype, int include_null)
Definition: monitor.c:279
struct target * target
Definition: target_api.h:2078
int probe_disable(struct probe *probe)
Definition: probe.c:1811
unsigned long tid
Definition: proxyreq.h:127
result_t
Definition: common.h:25
struct array_list * monitor_list_objs_by_objtype_lock_objtype(int objtype, int include_null)
Definition: monitor.c:315
int monitor_setup_stdout(struct monitor *monitor, int maxbufsiz, char *stdout_logfile, monitor_stdio_callback_t stdout_callback, void *callback_state)
Definition: monitor.c:1847
int vmi1__DisableProbe(struct soap *soap, vmi1__TargetIdT tid, vmi1__ProbeIdT pid, struct vmi1__NoneResponse *r)
Definition: target_rpc.c:2309
int vmi1__LookupTargetSymbol(struct soap *soap, vmi1__TargetIdT tid, char *name, struct vmi1__DebugFileOptsT *opts, struct vmi1__NestedSymbolResponse *r)
Definition: target_rpc.c:1377
target_status_t target_status(struct target *target)
Definition: target_api.c:1046
int vmi1__ListTargets(struct soap *soap, void *_, struct vmi1__TargetsResponse *r)
Definition: target_rpc.c:489
struct vmi1__SymbolT * symbol
void generic_rpc_fini(void)
Definition: generic_rpc.c:104
struct vmi1__SymbolsT * d_symbol_array_list_to_x_SymbolsT(struct soap *soap, struct array_list *list, struct vmi1__DebugFileOptsT *opts, GHashTable *reftab, struct array_list *refstack, int depth)
enum vmi1__TargetTypeT * targetType
int8_t REG
Definition: common.h:93
probepoint_style_t
Definition: probe_api.h:228
int target_finalize(struct target *target)
Definition: target.c:1955
struct target * target
Definition: probe.h:342
int proxyreq_handle_request(struct soap *soap, char *svc_name)
Definition: proxyreq.c:30
struct list_head action
Definition: probe.h:449
char * name
Definition: target_api.h:2521
char * infile
Definition: target_api.h:2286
int vmi1__InstantiateTarget(struct soap *soap, struct vmi1__TargetSpecT *spec, vmi1__ListenerT *ownerListener, struct vmi1__TargetResponse *r)
Definition: target_rpc.c:733
int generic_rpc_listener_notify_all(rpc_svctype_t svctype, int objid, generic_rpc_listener_notifier_t *notifier, void *data)
Definition: generic_rpc.c:902
int target_open(struct target *target)
Definition: target_api.c:513
target_status_t status
Definition: target_api.h:2503
int(* evloop_attach)(struct evloop *evloop, void *obj)
Definition: monitor.h:93
int vmi1__KillTarget(struct soap *soap, vmi1__TargetIdT tid, int kill_sig, struct vmi1__NoneResponse *r)
Definition: target_rpc.c:1255
int monitor_lookup_objid(int objid, int *objtype, void **obj, struct monitor **monitor)
Definition: monitor.c:219
int proxyreq_recv_response(struct monitor *monitor, struct monitor_msg *msg)
Definition: proxyreq.c:621
void monitor_init(void)
Definition: monitor.c:93
#define __SAFE_IO(fn, fns, fd, buf, buflen, rc)
Definition: generic_rpc.h:164
int vmi1__ProbeAddr(struct soap *soap, vmi1__TargetIdT tid, vmi1__ThreadIdT thid, char *probeName, vmi1__ADDR addr, vmi1__ProbepointTypeT *probepointType, vmi1__ProbepointStyleT *probepointStyle, vmi1__ProbepointWhenceT *probepointWhence, vmi1__ProbepointSizeT *probepointSize, struct vmi1__ProbeResponse *r)
Definition: target_rpc.c:2100
#define DEF_REFSTACK_SIZE
Definition: debuginfo_rpc.h:28
int vmi1__FinalizeTarget(struct soap *soap, vmi1__TargetIdT tid, struct vmi1__NoneResponse *r)
Definition: target_rpc.c:1285
int kill_on_close_sig
Definition: target_api.h:2242
result_t _target_rpc_probe_posthandler(struct probe *probe, tid_t tid, void *handler_data, struct probe *trigger, struct probe *base)
Definition: target_rpc.c:1945
struct target_spec * spec
Definition: target_api.h:2605
struct target * target_instantiate(struct target_spec *spec, struct evloop *evloop)
Definition: target_api.c:55
struct probe * probe_register_line(struct probe *probe, char *filename, int line, probepoint_style_t style, probepoint_whence_t whence, probepoint_watchsize_t watchsize)
Definition: probe.c:1403
int vmi1__LookupTargetLineSimple(struct soap *soap, vmi1__TargetIdT tid, char *filename, int line, struct vmi1__DebugFileOptsT *opts, struct vmi1__SymbolResponse *r)
Definition: target_rpc.c:1530
#define MONITORED_TARGET_LAUNCHER
Definition: target_rpc.h:38
action_type_t x_ActionTypeT_to_t_action_type_t(struct soap *soap, enum vmi1__ActionTypeT in)
Definition: target_xml.c:1492
void * malloc(size_t size)
Definition: debugserver.c:214
int id
Definition: target_api.h:2514
void probe_rename(struct probe *probe, const char *name)
Definition: probe.c:898
int vmi1__ListTargetTypes(struct soap *soap, void *_, struct vmi1__TargetTypesResponse *r)
Definition: target_rpc.c:469
struct array_list * chain
Definition: dwdebug.h:1016
struct monitor_objtype_ops target_rpc_monitor_objtype_ops
Definition: target_rpc.c:377
void generic_rpc_unregister_svctype(rpc_svctype_t svctype)
Definition: generic_rpc.c:195
char * errfile
Definition: target_api.h:2288
#define PROXY_REQUEST_LOCKED(soap, mobjid, mutex)
Definition: proxyreq.h:288
int monitor_destroy(struct monitor *monitor)
Definition: monitor.c:1039
char * outfile
Definition: target_api.h:2287
int generic_rpc_count_listeners(rpc_svctype_t svctype, int objid)
Definition: generic_rpc.c:880
struct probe * probe_register_symbol(struct probe *probe, struct bsymbol *bsymbol, probepoint_style_t style, probepoint_whence_t whence, probepoint_watchsize_t watchsize)
Definition: probe.c:1470
action_type_t
Definition: probe_api.h:249
int monitor_spawn(struct monitor *monitor, char *filename, char *const argv[], char *const envp[], char *dir)
Definition: monitor.c:2002
int action_sched(struct probe *probe, struct action *action, action_whence_t whence, action_handler_t handler, void *handler_data)
Definition: probe.c:4119
action_type_t type
Definition: probe.h:406
#define TID_GLOBAL
Definition: target_api.h:145
struct vmi1__ProbeT * t_probe_to_x_ProbeT(struct soap *soap, struct probe *probe, GHashTable *reftab, struct vmi1__ProbeT *out)
Definition: target_xml.c:1271
int vmi1__ResumeTarget(struct soap *soap, vmi1__TargetIdT tid, struct vmi1__NoneResponse *r)
Definition: target_rpc.c:1207
struct monitor * monitor_create(monitor_type_t type, monitor_flags_t flags, int objid, int objtype, void *obj, void *objstate)
Definition: monitor.c:1594
struct target * t
Definition: dumptarget.c:48
#define MONITOR_OBJTYPE_TARGET
Definition: target_rpc.h:35
struct vmi1__ProbeEventT event
Definition: target_rpc.c:1808
struct probe * probe_simple(struct target *target, tid_t tid, char *name, probe_handler_t pre_handler, probe_handler_t post_handler, void *handler_data)
Definition: probe_lib.c:37
monitor_error_t
Definition: monitor.h:54