"Fossies" - the Fresh Open Source Software Archive 
Member "FunctionCheck-3.2.0/src/fcmanager/main.c" (1 Jun 2012, 9374 Bytes) of package /linux/privat/old/FunctionCheck-3.2.0.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
1 /*
2 * FunctionCheck profiler
3 * (C) Copyright 2000-2012 Yannick Perret
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 /** main.c: started by the profiled program. reads and treats
20 the data sent by the profiled program. **/
21
22 #include <limits.h>
23 #include "fc_global.h"
24 #include "fc_tools.h"
25 #include "fc_com_manager.h"
26 #include "fc_time.h"
27 #include "fc_context.h"
28 #include "fc_functions.h"
29 #include "fc_graph.h"
30 #include "fc_stack.h"
31 #include "fc_xhash.h"
32 #include "fc_memory_manager.h"
33
34 /* well... it's the main, ya know... */
35 int main(int argc, char*argv[])
36 {
37 /* data returned at each 'read' */
38 void *function, *from, *incoming, *ptr, *where;
39 unsigned int size, align;
40 unsigned long long vtime;
41 char name[1024];
42 int shmid, id, ret, parent;
43 char type;
44 FC_Context *ctmp;
45 FC_Function *func;
46 unsigned long long ftime;
47 /* init structure with all default values */
48 FC_INIT init;
49 FC_LDYN ldyn;
50 /* special */
51 void *call_site;
52 char *usage = "Usage: " FC_MANAGER_NAME " is for internal used by libfc.so and automatically passed a <shared_mem_id> parameter.";
53 /* special case for thread: indicates that QUIT is done */
54 /*
55 int thread_quit_main = 0, thread_id_init = 0;
56 int thread_mode_init = 0;
57 */
58
59 /* set the prog name */
60 fc_set_message_name(FC_MANAGER_NAME);
61
62 /* check the parameters */
63 if (argc != 2)
64 {
65 fc_message(usage);
66 exit(FC_ERR_ARGS);
67 }
68
69 /* init the communication system */
70 shmid = atoi(argv[1]);
71 if (!fc_mcom_init(shmid, &id, &init)) /* id is the ID of the prog */
72 {
73 fc_message(usage);
74 exit(FC_ERR_ARGS);
75 }
76
77 /* init messages state */
78 fc_set_message_mode(init.verbose);
79 fc_set_debug_mode(init.debug);
80
81 /* init default values regard to the init info */
82 fc_context_set_functions(init.function_size);
83 fc_context_set_graph(init.graph_size);
84 fc_context_set_stack(init.stack_size);
85 fc_context_set_memory(init.memory_size);
86 fc_context_set_usepid(init.use_pid);
87 fc_context_set_name(init.dump_name);
88 fc_context_set_path(init.dump_path);
89 fc_memory_set_stack_size(init.memory);
90 fc_context_set_mode(init.mode);
91
92 /* if any read the list of dynamic libraries */
93 if (init.follow)
94 {
95 fc_mcom_read_lib(&ldyn);
96 while (ldyn.addr != NULL)
97 {
98 /* debug */
99 fc_message("Dyn lib: %s [0x%x]", ldyn.name[0] ? ldyn.name : "NULL", ldyn.addr);
100 fc_ldyn_add(&ldyn);
101 fc_mcom_read_lib(&ldyn);
102 }
103 }
104
105 fc_message("Profile manager: running [%d]", (int) getpid());
106
107 /* init the 1st context */
108 fc_context_set(id, init.start_time);
109
110 /* set starting time */
111 fc_context_set_starttime(time(NULL));
112
113 /* loop to read messages */
114 while (1)
115 {
116 /* read data */
117 /* removed. may not be useful now */
118 /*
119 if ((nb_children <= 0)||(thread_quit_main))
120 {
121 fc_message("no more children referenced. end of profiled program.");
122 fc_context_set_stoptime(time(NULL));
123 break;
124 }
125 */
126 ret = fc_mcom_read(&function, &from, &vtime, &id, &type,
127 &ptr, &incoming, &where, &parent, &size, &align, name);
128
129 fc_debug("%p %p %u %d %d", function, from, vtime, id, (int) type);
130 /* ret==0 => pipe closed => all clients are over */
131 if (!ret)
132 {
133 /* leave the reading loop */
134 fc_message("communication FIFO closed. end of profiled program.");
135 fc_context_set_stoptime(time(NULL));
136 break;
137 }
138
139 /** special messages **/
140 /* fork notification */
141 if (type == FC_TYPE_FORK)
142 {
143 /* set the context in order to
144 1/ create it as it is a new one
145 2/ set the starting time with the good value
146 */
147 fc_context_set(parent, vtime);
148
149 continue; /* just read next event */
150 }
151
152 /* thread creation notification */
153 if (type == FC_TYPE_THREAD)
154 {
155 /* set the context in order to
156 1/ create it as it is a new one
157 2/ set the starting time with the good value
158 */
159 fc_context_set(parent, vtime);
160
161 continue; /* just read next event */
162 }
163
164 /* set the corresponding context */
165 fc_context_set(id, vtime);
166
167 /* if QUIT event, only the time is used, so read next event */
168 if (type == FC_TYPE_QUIT)
169 {
170 fc_debug("QUIT message (%d). number of children is now (not yet implemented).", id);
171 continue;
172 /*nb_children--;
173 if ((thread_mode_init == FC_MODE_THREAD)&&(id == thread_id_init))
174 {
175 fc_debug("QUIT message from the main thread. Forced exit.");
176 thread_quit_main = 1;
177 }
178 continue;
179 */
180 }
181
182 /* set the last time found for this context */
183 fc_current_context->ulast_time = vtime;
184
185 /* test if the time loops */
186 if (vtime < fc_current_context->ulast_time)
187 {
188 fc_current_context->time_pad += UINT_MAX + 1;
189 }
190
191 fc_current_context->last_time = fc_current_context->time_pad + vtime;
192
193 /* special message to inform about the process aprent */
194 if (type == FC_TYPE_PARENT)
195 {
196 /* information on the parent process */
197 fc_current_context->pid = (int) parent;
198 }
199 else /* standard message. treat the data */
200 {
201 /* treat the action */
202 if (type == FC_TYPE_ENTER)
203 {
204 fc_functions_enter(function, from, fc_current_context->last_time);
205 }
206 else
207 if (type == FC_TYPE_EXIT)
208 {
209 if (function != NULL) /* NULL -> just an exit from prog */
210 {
211 /* first add the arc in the call-graph */
212 fc_debug("add arc %p -> %p", from, function);
213 fc_graph_add_single(fc_current_context->graph, from, function);
214 fc_functions_exit(function, from, fc_current_context->last_time);
215 }
216 else
217 {
218 fc_debug("process %d is over.", id);
219 }
220 }
221 else
222 if (type == FC_TYPE_MALLOC)
223 {
224 fc_memory_add_malloc(fc_current_context, ptr, size, where);
225 }
226 else
227 if (type == FC_TYPE_FREE)
228 {
229 fc_memory_add_free(fc_current_context, ptr, where);
230 }
231 else
232 if (type == FC_TYPE_REALLOC)
233 {
234 fc_memory_add_realloc(fc_current_context, ptr, incoming, size, where);
235 }
236 else
237 if (type == FC_TYPE_MEMALIGN)
238 {
239 fc_memory_add_memalign(fc_current_context, ptr, align, size, where);
240 }
241 else
242 {
243 if ((type == FC_TYPE_DLOPEN) || (type == FC_TYPE_DLCLOSE) ||
244 (type == FC_TYPE_DLSYM))
245 {
246 fc_message("this message type (%d) is not implemented.", (int) type);
247 }
248 else
249 {
250 fc_message("invalid message type (%d). ignored.", type);
251 }
252 }
253 }
254 }
255
256 /* for each context, flush the stack. the stack is not empty
257 if the profiled program stops due to a crash -> all remaining
258 functions are treated as if they exit now */
259 ctmp = fc_context_first();
260 while (ctmp != NULL)
261 {
262 fc_debug("context %p: flushing stack", ctmp);
263 fc_current_context = ctmp;
264 /* simulate exits for each remaining function */
265 while (!fc_stack_empty(ctmp->stack))
266 {
267 fc_stack_get(ctmp->stack, &func, &ftime, &call_site);
268 if (func->symbol != NULL)
269 {
270 fc_graph_add_single(fc_current_context->graph, call_site, func->symbol);
271 fc_functions_exit(func->symbol, NULL, ctmp->last_time);
272 }
273 else
274 fc_stack_pop(ctmp->stack);
275 }
276
277 ctmp = fc_context_next(ctmp);
278 }
279
280 /* dump data */
281 fc_debug("saving contexts");
282 fc_context_save_all();
283
284 /* stop communication system */
285 fc_mcom_fini(shmid);
286
287 /* exit */
288 fc_message("Profile manager: exit");
289 fc_debug("leaving fcmanager");
290 return FC_ERR_OK;
291 }