2 * Copyright (C) 2011 Mathieu Bain <mathieu.bain@polymtl.ca>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License Version 2 as
6 * published by the Free Software Foundation;
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include <sys/types.h>
23 #include <babeltrace/babeltrace.h>
25 #include "lttngtoptypes.h"
27 #include "iostreamtop.h"
29 void add_file(struct processtop
*proc
, struct files
*file
, int fd
)
31 struct files
*tmp_file
;
34 size
= proc
->process_files_table
->len
;
37 g_ptr_array_set_size(proc
->process_files_table
, fd
);
38 g_ptr_array_add(proc
->process_files_table
, file
);
40 tmp_file
= g_ptr_array_index(proc
->process_files_table
, fd
);
42 g_ptr_array_index(proc
->process_files_table
, fd
) = file
;
44 if (strcmp(tmp_file
->name
, file
->name
) != 0) {
45 size
= proc
->process_files_table
->len
;
46 g_ptr_array_set_size(proc
->process_files_table
,
48 g_ptr_array_index(proc
->process_files_table
,
50 g_ptr_array_index(proc
->process_files_table
,
53 tmp_file
->flag
= __NR_open
;
57 file
->flag
= __NR_open
;
62 void edit_file(struct processtop
*proc
, struct files
*file
, int fd
)
64 int size
= proc
->process_files_table
->len
;
65 struct files
*tmpfile
;
70 tmpfile
= g_ptr_array_index(proc
->process_files_table
, fd
);
71 tmpfile
->name
= strdup(file
->name
);
76 void insert_file(struct processtop
*proc
, int fd
)
80 if (fd
>= proc
->process_files_table
->len
) {
81 tmp
= g_new0(struct files
, 1);
82 tmp
->name
= "Unknown";
86 add_file(proc
, tmp
, fd
);
89 tmp
= g_ptr_array_index(proc
->process_files_table
, fd
);
91 tmp
= g_new0(struct files
, 1);
92 tmp
->name
= "Unknown";
96 add_file(proc
, tmp
, fd
);
101 void close_file(struct processtop
*proc
, int fd
)
106 file
= get_file(proc
, fd
);
108 file
->flag
= __NR_close
;
111 struct files
*get_file(struct processtop
*proc
, int fd
)
114 struct files
*tmp
= NULL
;
116 len
= proc
->process_files_table
->len
;
119 * It is possible that a file was open before taking the trace
120 * and its fd could be greater than all of the others fd
121 * used by the process
123 if (fd
< len
&& fd
>= 0)
124 tmp
= g_ptr_array_index(proc
->process_files_table
, fd
);
129 void show_table(GPtrArray
*tab
)
134 for (i
= 0 ; i
< tab
->len
; i
++) {
135 file
= g_ptr_array_index(tab
, i
);
137 fprintf(stderr
, "NULL, ");
139 fprintf(stderr
, "%s, ", file
->name
);
141 fprintf(stderr
, "]\n\n");
144 void show_history(struct file_history
*history
)
146 struct file_history
*tmp
= history
;
148 while (tmp
!= NULL
) {
149 fprintf(stderr
, "fd = %d, name = %s\n", tmp
->file
->fd
,
156 int update_iostream_ret(struct lttngtop
*ctx
, int tid
, char *comm
,
157 unsigned long timestamp
, uint64_t cpu_id
, int ret
)
159 struct processtop
*tmp
;
160 struct files
*tmpfile
;
163 tmp
= get_proc(ctx
, tid
, comm
, timestamp
);
165 if (tmp
->syscall_info
!= NULL
) {
166 if (tmp
->syscall_info
->type
== __NR_read
168 tmp
->totalfileread
+= ret
;
169 tmp
->fileread
+= ret
;
170 tmpfile
= get_file(tmp
, tmp
->syscall_info
->fd
);
171 tmpfile
->read
+= ret
;
172 } else if (tmp
->syscall_info
->type
== __NR_write
174 tmp
->totalfilewrite
+= ret
;
175 tmp
->filewrite
+= ret
;
176 tmpfile
= get_file(tmp
, tmp
->syscall_info
->fd
);
177 tmpfile
->write
+= ret
;
178 } else if (tmp
->syscall_info
->type
== __NR_open
180 tmpfile
= tmp
->files_history
->file
;
181 add_file(tmp
, tmpfile
, ret
);
186 g_free(tmp
->syscall_info
);
187 tmp
->syscall_info
= NULL
;
192 struct syscalls
*create_syscall_info(unsigned int type
, uint64_t cpu_id
,
193 unsigned int tid
, int fd
)
195 struct syscalls
*syscall_info
;
197 syscall_info
= g_new0(struct syscalls
, 1);
198 syscall_info
->type
= type
;
199 syscall_info
->cpu_id
= cpu_id
;
200 syscall_info
->tid
= tid
;
201 syscall_info
->fd
= fd
;
206 struct file_history
*create_file(struct file_history
*history
, char *file_name
)
208 struct files
*new_file
;
209 struct file_history
*new_history
;
211 new_file
= g_new0(struct files
, 1);
212 new_history
= g_new0(struct file_history
, 1);
213 new_file
->name
= strdup(file_name
);
216 new_history
->file
= new_file
;
217 new_history
->next
= history
;
222 enum bt_cb_ret
handle_exit_syscall(struct bt_ctf_event
*call_data
,
225 const struct definition
*scope
;
226 unsigned long timestamp
;
231 timestamp
= bt_ctf_get_timestamp(call_data
);
232 if (timestamp
== -1ULL)
235 comm
= get_context_comm(call_data
);
236 tid
= get_context_tid(call_data
);
238 scope
= bt_ctf_get_top_level_scope(call_data
,
240 ret
= bt_ctf_get_int64(bt_ctf_get_field(call_data
,
242 if (bt_ctf_field_get_error()) {
243 fprintf(stderr
, "Missing ret context info\n");
247 cpu_id
= get_cpu_id(call_data
);
250 * if we encounter an exit_syscall and
251 * it is not for a syscall read or write
252 * we just abort the execution of this callback
254 if ((update_iostream_ret(<tngtop
, tid
, comm
, timestamp
, cpu_id
, ret
)) < 0)
255 return BT_CB_ERROR_CONTINUE
;
260 return BT_CB_ERROR_STOP
;
264 enum bt_cb_ret
handle_sys_write(struct bt_ctf_event
*call_data
,
267 const struct definition
*scope
;
268 struct processtop
*tmp
;
269 unsigned long timestamp
;
275 timestamp
= bt_ctf_get_timestamp(call_data
);
276 if (timestamp
== -1ULL)
279 comm
= get_context_comm(call_data
);
280 tid
= get_context_tid(call_data
);
281 cpu_id
= get_cpu_id(call_data
);
283 scope
= bt_ctf_get_top_level_scope(call_data
,
285 fd
= bt_ctf_get_uint64(bt_ctf_get_field(call_data
,
287 if (bt_ctf_field_get_error()) {
288 fprintf(stderr
, "Missing fd context info\n");
292 tmp
= get_proc(<tngtop
, tid
, comm
, timestamp
);
293 tmp
->syscall_info
= create_syscall_info(__NR_write
, cpu_id
, tid
, fd
);
295 insert_file(tmp
, fd
);
300 return BT_CB_ERROR_STOP
;
303 enum bt_cb_ret
handle_sys_read(struct bt_ctf_event
*call_data
,
306 struct processtop
*tmp
;
307 const struct definition
*scope
;
308 unsigned long timestamp
;
314 timestamp
= bt_ctf_get_timestamp(call_data
);
315 if (timestamp
== -1ULL)
318 comm
= get_context_comm(call_data
);
319 tid
= get_context_tid(call_data
);
320 cpu_id
= get_cpu_id(call_data
);
322 scope
= bt_ctf_get_top_level_scope(call_data
,
324 fd
= bt_ctf_get_uint64(bt_ctf_get_field(call_data
,
326 if (bt_ctf_field_get_error()) {
327 fprintf(stderr
, "Missing fd context info\n");
331 tmp
= get_proc(<tngtop
, tid
, comm
, timestamp
);
332 tmp
->syscall_info
= create_syscall_info(__NR_read
, cpu_id
, tid
, fd
);
334 insert_file(tmp
, fd
);
339 return BT_CB_ERROR_STOP
;
343 enum bt_cb_ret
handle_sys_open(struct bt_ctf_event
*call_data
,
347 struct processtop
*tmp
;
348 const struct definition
*scope
;
349 unsigned long timestamp
;
355 timestamp
= bt_ctf_get_timestamp(call_data
);
356 if (timestamp
== -1ULL)
359 comm
= get_context_comm(call_data
);
360 tid
= get_context_tid(call_data
);
361 cpu_id
= get_cpu_id(call_data
);
363 scope
= bt_ctf_get_top_level_scope(call_data
,
365 file
= bt_ctf_get_string(bt_ctf_get_field(call_data
,
366 scope
, "_filename"));
367 if (bt_ctf_field_get_error()) {
368 fprintf(stderr
, "Missing file name context info\n");
372 tmp
= get_proc(<tngtop
, tid
, comm
, timestamp
);
373 tmp
->syscall_info
= create_syscall_info(__NR_open
, cpu_id
, tid
, -1);
375 tmp
->files_history
= create_file(tmp
->files_history
, file
);
380 return BT_CB_ERROR_STOP
;
384 enum bt_cb_ret
handle_sys_close(struct bt_ctf_event
*call_data
,
387 const struct definition
*scope
;
388 unsigned long timestamp
;
390 struct processtop
*tmp
;
394 timestamp
= bt_ctf_get_timestamp(call_data
);
395 if (timestamp
== -1ULL)
398 comm
= get_context_comm(call_data
);
399 tid
= get_context_tid(call_data
);
401 scope
= bt_ctf_get_top_level_scope(call_data
,
403 fd
= bt_ctf_get_uint64(bt_ctf_get_field(call_data
,
405 if (bt_ctf_field_get_error()) {
406 fprintf(stderr
, "Missing fd context info\n");
410 tmp
= get_proc(<tngtop
, tid
, comm
, timestamp
);
417 return BT_CB_ERROR_STOP
;
420 enum bt_cb_ret handle_statedump_file_descriptor(struct bt_ctf_event *call_data,
423 struct definition *scope;
425 unsigned long timestamp;
427 struct processtop *tmp;
428 char *comm, *file_name;
431 timestamp = bt_ctf_get_timestamp(call_data);
432 if (timestamp == -1ULL)
435 comm = get_context_comm(call_data);
437 scope = bt_ctf_get_top_level_scope(call_data,
439 tid = bt_ctf_get_uint64(bt_ctf_get_field(call_data,
441 if (bt_ctf_field_get_error()) {
442 fprintf(stderr, "Missing tid context info\n");
446 scope = bt_ctf_get_top_level_scope(call_data,
448 fd = bt_ctf_get_uint64(bt_ctf_get_field(call_data,
450 if (bt_ctf_field_get_error()) {
451 fprintf(stderr, "Missing fd context info\n");
455 scope = bt_ctf_get_top_level_scope(call_data,
457 file_name = bt_ctf_get_string(bt_ctf_get_field(call_data,
458 scope, "_filename"));
459 if (bt_ctf_field_get_error()) {
460 fprintf(stderr, "Missing file name context info\n");
464 file = g_new0(struct files, 1);
465 file->name = strdup(file_name);
467 tmp = find_process_tid(<tngtop, tid, comm);
468 edit_file(tmp, file, fd);
470 fprintf(stderr, "%lu %s\n", tmp->tid, file_name);
475 return BT_CB_ERROR_STOP;
This page took 0.03814 seconds and 4 git commands to generate.