⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 process.c

📁 memprof source code, linux
💻 C
📖 第 1 页 / 共 2 页
字号:
	return process->block_table;		}static StackStash *get_stack_stash (MPProcess *process){	if (!process->stack_stash)		process->stack_stash = stack_stash_new ();	return process->stack_stash;}voidprocess_exec_reset (MPProcess *process){	process_reinit (process);	g_signal_emit_by_name (process, "reset");}static voidprocess_command (MPProcess *process, MIInfo *info, StackElement *stack){	GHashTable *block_table;	Block *block;	static lont int  max_use = 0;	if (info->any.seqno != process->seqno) {		queue_command (process, info, stack);		return;	}	process->seqno++;	block = NULL;		switch (info->operation) {	case MI_NEW:	case MI_FORK:	case MI_CLONE:	case MI_EXEC:		g_assert_not_reached ();		break;			case MI_EXIT:		/* Handled before, ignore */		break;			default: /* MALLOC / REALLOC / FREE */		block_table = get_block_table (process);				if (info->alloc.old_ptr != NULL) {			block = g_hash_table_lookup (block_table, info->alloc.old_ptr);			if (!block) {				g_warning ("Block %p not found (pid=%d)!\n", info->alloc.old_ptr, process->pid);				process_dump_stack (process, stderr, stack);			}			else {				g_hash_table_remove (block_table, info->alloc.old_ptr);				process->bytes_used -= block->size;				block_unref (block);								process->n_allocations--;			}		}		/* We need to lookup before inserting, because realloc() can call malloc(), so we		 * see the same block twice. The same problem comes upduring malloc initialization		 * where __libc_malloc() is called twice for the same block. We could optimize		 * things a bit by using g_hash_table_new_full() to catch the replacement when		 * it happens and free the old block, but that would make keeping track of		 * process->n_allocations/bytes_used a little difficult.		 */		if (info->alloc.new_ptr && !g_hash_table_lookup (block_table, info->alloc.new_ptr)) {			block = g_new (Block, 1);			block->refcount = 1;						block->flags = 0;			block->addr = info->alloc.new_ptr;			block->size = info->alloc.size;			block->stack = stack;						process->n_allocations++;			process->bytes_used += info->alloc.size;			if (max_use < process->bytes_used)				max_use = process->bytes_used;			printf(" byte use = %ld, max_use = %d\n", process->bytes_used, max_use);			g_hash_table_insert (block_table, info->alloc.new_ptr, block);		}	}	while (process->command_queue && unqueue_command (process, info, &stack))		process_command (process, info, stack);}static gboolean input_func (GIOChannel  *source,	    GIOCondition condition,	    gpointer     data){	MIInfo info;	guint count;	MPProcess *input_process = data;	MPProcess *process = NULL;  	g_io_channel_read (source, (char *)&info, sizeof(info), &count);	if (count == 0) {		g_io_channel_unref (input_process->input_channel);		input_process->input_channel = NULL;		mp_server_remove_process (input_process->server, input_process);		process_set_status (input_process, MP_PROCESS_DEFUNCT);				return FALSE;	} else {		StackElement *stack = NULL;		if (info.operation == MI_MALLOC ||		    info.operation == MI_REALLOC ||		    info.operation == MI_FREE) {			void **stack_buffer = NULL;			StackStash *stash = get_stack_stash (input_process);						stack_buffer = g_alloca (sizeof (void *) * info.alloc.stack_size);			g_io_channel_read (source, (char *)stack_buffer, sizeof(void *) * info.alloc.stack_size, &count);			stack = stack_stash_store (stash, stack_buffer, info.alloc.stack_size);		} else if (info.operation == MI_EXIT) {			process_set_status (input_process, MP_PROCESS_EXITING);			if (input_process->clone_of)				process_detach (input_process);		}				process = input_process;		while (process->clone_of)			process = process->clone_of;				process_command (process, &info, stack);/*		if (info.any.pid != input_process->pid)		g_warning ("Ow! Ow! Ow: %d %d %d!", info.any.pid, input_process->pid, g_io_channel_unix_get_fd (input_process->input_channel)); */	}  	return TRUE;}voidprocess_stop_input (MPProcess *process){	g_return_if_fail (process != NULL);  	if (process->input_tag) {		g_source_remove (process->input_tag);		process->input_tag = 0;	}}voidprocess_start_input (MPProcess *process){	g_return_if_fail (process != NULL);  	if (!process->input_tag && process->input_channel)		process->input_tag = g_io_add_watch_full (process->input_channel,							  G_PRIORITY_LOW,							  G_IO_IN | G_IO_HUP,							  input_func, process, NULL);}char *process_find_exec (char **args){	int i;  	if (g_file_exists(args[0])) {		if (!g_path_is_absolute (args[0]))			return g_strconcat ("./", args[0], NULL);		else			return g_strdup (args[0]);	} else {		char **paths;		char *path = NULL;		char *pathenv = getenv ("PATH");		if (pathenv)		{			paths = g_strsplit (pathenv, ":", -1);			for (i=0; paths[i]; i++) {				path = g_concat_dir_and_file (paths[i], args[0]);				if (g_file_exists (path))					break;				else {					g_free (path);					path = NULL;				}			}			g_strfreev (paths);		}		return path;	}}char **process_parse_exec (const char *exec_string){	return g_strsplit (exec_string, " ", -1);}GTypemp_process_get_type (void){	static GType process_type = 0;	if (!process_type) {		static const GTypeInfo process_info = {			sizeof (MPProcessClass),			(GBaseInitFunc) NULL,			(GBaseFinalizeFunc) NULL,			(GClassInitFunc) mp_process_class_init,			NULL, /* class_finalize */			NULL, /* class_data */			sizeof (MPProcess),			0, /* n_preallocs */			(GInstanceInitFunc) mp_process_init		};		process_type = g_type_register_static (G_TYPE_OBJECT,						       "MPProcess",						       &process_info, 0);	}	return process_type;}static voidmp_process_class_init (MPProcessClass *class){	static gboolean initialized = FALSE;	GObjectClass *o_class = G_OBJECT_CLASS (class);	o_class->finalize = mp_process_finalize;	if (!initialized) {		process_signals[STATUS_CHANGED] =			g_signal_new ("status_changed",			              MP_TYPE_PROCESS,			              G_SIGNAL_RUN_LAST,			              G_STRUCT_OFFSET (MPProcessClass, status_changed),			              NULL, NULL,			              g_cclosure_marshal_VOID__VOID,			              G_TYPE_NONE, 0);				process_signals[RESET] =			g_signal_new ("reset",			              MP_TYPE_PROCESS,			              G_SIGNAL_RUN_LAST,			              G_STRUCT_OFFSET (MPProcessClass, reset),				      NULL, NULL,			              g_cclosure_marshal_VOID__VOID,			              G_TYPE_NONE, 0);		initialized = TRUE;	}}static voidmp_process_init (MPProcess *process){	process->status = MP_PROCESS_INIT;	process->pid = 0;	process->clone_of = NULL;  	process->bytes_used = 0;	process->n_allocations = 0;	process->block_table = NULL;	process->stack_stash = NULL;	process->program_name = NULL;	process->input_channel = NULL;	process->seqno = 0;	process->command_queue = NULL;	process->follow_fork = FALSE;	process->follow_exec = FALSE;	g_object_ref (G_OBJECT (process));}static void mp_process_finalize (GObject *object){	MPProcess *process = MP_PROCESS (object);	process_reinit (process);		g_free (process->program_name);}MPProcess *process_new (MPServer *server){	MPProcess *process;	process = g_object_new (MP_TYPE_PROCESS, NULL);	process->server = server;	return process;}voidprocess_set_follow_fork (MPProcess *process,			 gboolean   follow_fork){	process->follow_fork = follow_fork;}voidprocess_set_follow_exec (MPProcess *process,			 gboolean   follow_exec){	process->follow_exec = follow_exec;}voidprocess_run (MPProcess *process, const char *path, char **args){	process->program_name = g_strdup (path);	read_inode (path);	process->pid = mp_server_instrument (process->server, path, args);	mp_server_add_process (process->server, process);	process_set_status (process, MP_PROCESS_STARTING);  	process_start_input (process);}GList *process_get_clones (MPProcess *process){	return mp_server_get_process_clones (process->server, process);}voidprocess_set_status (MPProcess *process, MPProcessStatus status){	if (process->status != status) {		process->status = status;		g_signal_emit_by_name (process, "status_changed", NULL);	}}char *process_get_status_text (MPProcess *process){	char *status = "";		switch (process->status) {	case MP_PROCESS_INIT:		status = _("Initial");		break;	case MP_PROCESS_STARTING:		status = _("Starting");		break;	case MP_PROCESS_RUNNING:		status = _("Running");		break;	case MP_PROCESS_EXITING:		status = _("Exiting");		break;	case MP_PROCESS_DEFUNCT:		status = _("Defunct");		break;	case MP_PROCESS_DETACHED:		status = _("Defunct");		break;	}	return g_strdup (status);}char *process_get_cmdline (MPProcess *process){	char *fname;	char *result;	char *tmp = NULL;	int n = 0;	FILE *in = NULL;	if (process->status == MP_PROCESS_DEFUNCT)		return g_strdup ("");		fname = g_strdup_printf ("/proc/%d/cmdline", process->pid);	in = fopen (fname, "r");	if (!in) {		g_warning ("Can't open %s\n", fname);		return g_strdup ("");	}	g_free (fname);	getline (&tmp, &n, in);	result = g_strdup (tmp);	free (tmp);	fclose (in);	return result;}voidprocess_detach (MPProcess *process){	if (process->status != MP_PROCESS_DEFUNCT) {		int fd = g_io_channel_unix_get_fd (process->input_channel);		if (process->status == MP_PROCESS_EXITING) {			char response = 0;			write (fd, &response, 1);		} else {			g_io_channel_close (process->input_channel);			process_set_status (process, MP_PROCESS_DETACHED);		}	}}voidprocess_kill (MPProcess *process){	if (process->status == MP_PROCESS_EXITING) {		process_detach (process);	} else if (process->status != MP_PROCESS_DEFUNCT &&		   process->status != MP_PROCESS_INIT) {		kill (process->pid, SIGTERM);	}}typedef struct {	MPProcessBlockForeachFunc foreach_func;	gpointer data;} BlockForeachInfo;static voidblock_table_foreach_func (gpointer key,			  gpointer value,			  gpointer data){	BlockForeachInfo *info = data;	info->foreach_func (value, info->data);}voidprocess_block_foreach (MPProcess                 *process,		       MPProcessBlockForeachFunc  foreach_func,		       gpointer                   data){	GHashTable *block_table = get_block_table (process);	BlockForeachInfo info;	info.foreach_func = foreach_func;	info.data = data;	g_hash_table_foreach (block_table, block_table_foreach_func, &info);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -