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_process.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 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 <assert.h>
20 #include <glib.h>
21 
22 #include "common.h"
23 #include "glib_wrapper.h"
24 #include "object.h"
25 #include "target.h"
26 #include "target_process.h"
27 
44  struct target_thread *tthread,
45  struct addrspace *space) {
46  struct target_process *process;
47 
48  assert(target);
49  assert(tthread);
50 
51  process = (struct target_process *)calloc(1,sizeof(*process));
52 
53  process->target = target;
54  RHOLDW(target,process);
55 
56  process->threads = g_hash_table_new(g_direct_hash,g_direct_equal);
57  process->children = g_hash_table_new(g_direct_hash,g_direct_equal);
58 
59  process->thread = tthread;
60  process->tid = tthread->tid;
61  RHOLD(tthread,process);
62  g_hash_table_insert(process->threads,
63  (gpointer)(uintptr_t)tthread->tid,tthread);
64 
65  process->space = space;
66  if (space) {
67  RHOLD(space,process);
68  }
69 
70  return process;
71 }
72 
82  obj_flags_t orf,obj_flags_t nandf) {
83  return;
84 }
85 
86 REFCNT target_process_free(struct target_process *process,int force) {
87  REFCNT trefcnt;
88  REFCNT retval;
89  GHashTableIter iter;
90  gpointer vp;
91  struct target_process *child;
92  struct target_thread *tthread;
93 
94  assert(process);
95 
96  if (process->refcnt) {
97  if (!force) {
98  verror("cannot free (%d refs) process %"PRIiTID"\n",
99  process->refcnt,process->tid);
100  return process->refcnt;
101  }
102  else {
103  vwarn("forcing free (%d refs) process %"PRIiTID"\n",
104  process->refcnt,process->tid);
105  }
106  }
107 
108  RWGUARD(process);
109 
110  vdebug(8,LA_TARGET,LF_PROCESS,"freeing process %d\n",process->tid);
111 
112  /* Free our children... */
113  g_hash_table_iter_init(&iter,process->children);
114  while (g_hash_table_iter_next(&iter,NULL,&vp)) {
115  child = (struct target_process *)vp;
116  RPUT(child,target_process,process,trefcnt);
117  g_hash_table_iter_remove(&iter);
118  }
119 
120  if (process->refcntw) {
121  if (!force) {
123  "cannot free (%d wrefs) process %"PRIiTID"\n",
124  process->refcntw,process->tid);
125  RWUNGUARD(process);
126  return process->refcntw;
127  }
128  else {
129  vwarn("forcing free (%d refs) process %"PRIiTID"\n",
130  process->refcntw,process->tid);
131  }
132  }
133 
134  g_hash_table_iter_init(&iter,process->threads);
135  while (g_hash_table_iter_next(&iter,NULL,&vp)) {
136  tthread = (struct target_thread *)vp;
137  RPUT(tthread,target_thread,process,trefcnt);
138  }
139  g_hash_table_destroy(process->threads);
140  process->threads = NULL;
141  process->thread = NULL;
142  process->tid = 0;
143 
144  g_hash_table_iter_init(&iter,process->children);
145  while (g_hash_table_iter_next(&iter,NULL,&vp)) {
146  child = (struct target_process *)vp;
147  /* Best we can do, if we're forcing. */
148  child->parent = NULL;
149  }
150  g_hash_table_destroy(process->children);
151  process->children = NULL;
152 
153  if (process->parent) {
154  RPUTW(process->parent,target_process,process,trefcnt);
155  process->parent = NULL;
156  }
157 
158  if (process->space) {
159  RPUT(process->space,addrspace,process,trefcnt);
160  process->space = NULL;
161  }
162 
163  if (process->target) {
164  RPUTW(process->target,target,process,trefcnt);
165  process->target = NULL;
166  }
167 
168  retval = process->refcnt + process->refcntw - 1;
169 
170  free(process);
171 
172  return retval;
173 }
#define RPUTW(x, objtype, hx, rc)
Definition: common.h:628
struct addrspace * space
#define RHOLDW(x, hx)
Definition: common.h:623
#define RWUNGUARD(x)
Definition: common.h:221
REFCNT target_process_free(struct target_process *process, int force)
#define assert(x)
Definition: dlmalloc.c:1456
struct target_process * target_process_create(struct target *target, struct target_thread *tthread, struct addrspace *space)
#define verror(format,...)
Definition: log.h:30
GHashTable * children
#define vwarn(format,...)
Definition: log.h:33
void free(void *ptr)
Definition: debugserver.c:207
#define RHOLD(x, hx)
Definition: common.h:622
#define vdebug(devel, areas, flags, format,...)
Definition: log.h:302
obj_flags_t
Definition: object.h:43
struct target * target
void * calloc(size_t nmemb, size_t size)
Definition: debugserver.c:200
Definition: log.h:70
#define PRIiTID
Definition: common.h:37
void target_process_obj_flags_propagate(struct target_process *process, obj_flags_t orf, obj_flags_t nandf)
GHashTable * threads
uint32_t REFCNT
Definition: common.h:124
struct target_process * parent
#define RPUT(x, objtype, hx, rc)
Definition: common.h:624
struct target_thread * thread
#define RWGUARD(x)
Definition: common.h:220