Example #1
0
File: process.c Project: 8l/FUZIX
/* This sees if the current process has any signals set, and handles them.
 */
void chksigs(void)
{
	uint8_t j;
	uint32_t pending = udata.u_ptab->p_pending & ~udata.u_ptab->p_held;
	int (**svec)(int) = &udata.u_sigvec[0];
	uint32_t m;

	/* Fast path - no signals pending means no work
	   Also don't do signal processing if we are in P_STOPPED. This
	   isn't quite right but will paper over the holes for the moment
	   FIXME */
	if (!pending || udata.u_ptab->p_status == P_STOPPED)
		return;

	/* Dispatch the lowest numbered signal */
	for (j = 1; j < NSIGS; ++j) {
		svec++;
		m = sigmask(j);
		if (!(m & pending))
			continue;
	        /* SIGSTOP can't be ignored and puts the process into
	           P_STOPPED state when it is ready to handle the signal.
	           Annoyingly right now we have to context switch to the task
	           in order to stop it in the right place. That would be nice
	           to fix */
	        if (j == SIGSTOP || j == SIGTTIN || j == SIGTTOU) {
			udata.u_ptab->p_status = P_STOPPED;
			udata.u_ptab->p_event = j;
			psleep(NULL);
                }
		/* This is more complex than in V7 - we have multiple
		   behaviours (plus the unimplemented as yet core dump) */
		if (*svec == SIG_DFL) {
			/* SIGCONT is subtle - we woke the process to handle
			   the signal so ignoring here works fine */
			if (j == SIGCHLD || j == SIGURG || j == SIGSTOP ||
                            j == SIGTTIN || j == SIGTTOU ||
			    j == SIGIO || j == SIGCONT || udata.u_ptab->p_pid == 1) {
				udata.u_ptab->p_pending &= ~m;	// unset the bit
				continue;
			}
			/* FIXME: core dump on some signals */
#ifdef DEBUG
			kprintf("process terminated by signal %d\n", j);
#endif
                        doexit(dump_core(j));
		} else if (*svec != SIG_IGN) {
			/* Arrange to call the user routine at return */
			udata.u_ptab->p_pending &= ~m;	// unset the bit
#ifdef DEBUG
			kprintf("about to process signal %d\n", j);
#endif
			udata.u_cursig = j;
			break;
		}
	}
}
Example #2
0
void signal_frame(uint8_t *trapframe, uint32_t d0, uint32_t d1, uint32_t a0,
	uint32_t a1)
{
	extern void *udata_shadow;
	uint8_t *usp = get_usp();
	udata_ptr = udata_shadow;
	uint16_t ccr = *(uint16_t *)trapframe;
	uint32_t addr = *(uint32_t *)(trapframe + 2);
	int err = 0;

	/* Build the user stack frame */

	/* FIXME: eventually we should put the trap frame details and trap
	   info into the frame */
	usp -= 4;
	err |= uputl(addr, usp);
	usp -= 4;
	err |= uputw(ccr, usp);
	usp -= 2;
	err |=uputl(a1, usp);
	usp -= 4;
	err |= uputl(a0, usp);
	usp -= 4;
	err |= uputl(d1, usp);
	usp -= 4;
	err |= uputl(d0, usp);
	usp -= 4;
	err |= uputl(udata.u_codebase + 4, usp);
	set_usp(usp);

	if (err) {
		kprintf("%d: stack fault\n", udata.u_ptab->p_pid);
		doexit(dump_core(SIGKILL));
	}
	/* Now patch up the kernel frame */
	*(uint16_t *)trapframe = 0;
	*(uint32_t *)(trapframe + 2) = (uint32_t)udata.u_sigvec[udata.u_cursig];
	udata.u_sigvec[udata.u_cursig] = SIG_DFL;
	udata.u_cursig = 0;
}
Example #3
0
/**************************************************************************** **
 possibly continue after a fault
 **************************************************************************** */
static void fault_continue(void)
{
#if DUMP_CORE
  dump_core();
#endif
} /* fault_continue */
Example #4
0
static void fault_continue(void)
{
	dump_core();
}
Example #5
0
static void tracer_dump(pid_t pid) {

  /* Read arguments from tracee */
  handle_events_until_dump_trap(-1);
  register_t ret = get_arg_from_regs(pid);
  assert(ret == TRAP_START_ARGS);

  debug_print("receive string from tracee %d\n", pid);
  ptrace_getdata(pid, (long) tracer_buff->str_tmp, loop_name, SIZE_LOOP);
  ptrace_syscall(pid);

  invocation = (int)receive_from_tracee(pid);
  ptrace_syscall(pid);

  int arg_count = (int)receive_from_tracee(pid);
  ptrace_syscall(pid);

  printf("DUMP( %s %d count = %d) \n", loop_name, invocation, arg_count);

  /* Ensure that the dump directory exists */
  snprintf(dump_path, sizeof(dump_path), "%s/%s/%s", dump_prefix, dump_root,
           loop_name);

  mkdir(dump_path, 0777);

  snprintf(dump_path, sizeof(dump_path), "%s/%s/%s/%d", dump_prefix, dump_root,
           loop_name, invocation);

  if (mkdir(dump_path, 0777) != 0)
    errx(EXIT_FAILURE, "dump %s already exists, stop\n", dump_path);

  int i;
  void *addresses[arg_count];
  for (i = 0; i < arg_count; i++) {
    addresses[i] = (void *)receive_from_tracee(pid);
    ptrace_syscall(pid);
  }

  /* Wait for end of arguments sigtrap */
  handle_events_until_dump_trap(pid);
  ret = get_arg_from_regs(pid);
  assert(ret == TRAP_END_ARGS);

  /* Dump hotpages to disk */
  flush_hot_pages_trace_to_disk(pid);

  char lel_bin_path[1024];
  /* Link to the original binary */
  snprintf(lel_bin_path, sizeof(lel_bin_path), "%s/lel_bin", dump_path);
  int res =
      linkat(AT_FDCWD, "lel_bin", AT_FDCWD, lel_bin_path, AT_SYMLINK_FOLLOW);
  if (res == -1)
    errx(EXIT_FAILURE, "Error copying the dump binary\n");

  for (i = 0; i < arg_count; i++) {
    void *start_of_page = round_to_page(addresses[i]);
    if (start_of_page != NULL) {
      unprotect_i(pid, start_of_page, PAGESIZE);
      dump_page(pid, start_of_page);
    }
  }

  if (firsttouch_active) {
    dump_firsttouch();
  }

  dump_core(arg_count, addresses);
  dump_unprotected_pages(pid);
}
Example #6
0
static void fault_quit(void)
{
#if DUMP_CORE
	dump_core();
#endif
}
Example #7
0
static void fault_quit(void)
{
	dump_core();
}
Example #8
0
uint8_t chksigs(void)
{
	uint8_t j;
	uint32_t pending = udata.u_ptab->p_pending & ~udata.u_ptab->p_held;
	int (**svec)(int) = &udata.u_sigvec[0];
	uint32_t m;

	/* Fast path - no signals pending means no work.
	   Cursig being set means we've already worked out what to do.
	 */

rescan:
	if (udata.u_cursig || !pending || udata.u_ptab->p_status == P_STOPPED)
		return udata.u_cursig;

	/* Dispatch the lowest numbered signal */
	for (j = 1; j < NSIGS; ++j) {
		svec++;
		m = sigmask(j);
		if (!(m & pending))
			continue;
		/* This is more complex than in V7 - we have multiple
		   behaviours plus core dump */
		if (*svec == SIG_DFL) {
		        /* SIGSTOP can't be ignored and puts the process into
		           P_STOPPED state when it is ready to handle the signal.
		           Annoyingly right now we have to context switch to the task
		           in order to stop it in the right place. That would be nice
		           to fix */
		        if (m & stopper) {
				/* Don't allow us to race SIGCONT */
				irqflags_t irq = di();
				/* FIXME: can we ever end up here not in READY/RUNNING ? */
				nready--;
				udata.u_ptab->p_status = P_STOPPED;
				udata.u_ptab->p_event = j;
				udata.u_ptab->p_pending &= ~m;	// unset the bit
				irqrestore(irq);
				switchout();
				/* Other things may have happened */
				goto rescan;
	                }

			/* The signal is being handled, so clear it even if
			   we are exiting (otherwise we'll loop in
			   chksigs) */
			udata.u_ptab->p_pending &= ~m;

	                if ((m & clear) || udata.u_ptab->p_pid == 1) {
			/* SIGCONT is subtle - we woke the process to handle
			   the signal so ignoring here works fine */
				continue;
			}
#ifdef DEBUG
			kprintf("process terminated by signal %d\n", j);
#endif
			/* We may have marked ourselves as asleep and
			   then been caught by the chksigs when we tried
			   to task switch into bed. In that case we need
			   to put the process back in running state */
			if (udata.u_ptab->p_status == P_SLEEP) {
				udata.u_ptab->p_status = P_RUNNING;
				nready++;
			}
			doexit(dump_core(j));
		} else if (*svec != SIG_IGN) {
			/* Arrange to call the user routine at return */
			udata.u_ptab->p_pending &= ~m;	// unset the bit
#ifdef DEBUG
			kprintf("about to process signal %d\n", j);
#endif
			udata.u_cursig = j;
			break;
		}
	}
	return udata.u_cursig;
}
Example #9
0
int exception(struct trapdata *framedata)
{
	ptptr proc;
	unsigned int frame, fsize;
	uint8_t trap = framedata->trap;
	unsigned int sig = 0;
	uint16_t m;
	uint16_t *sp = (uint16_t *)framedata;
	uint16_t *usp = get_usp();
	uint16_t *unwind, *context;
	uint8_t err = 0;
	int i;

	/* We translate debug to SIGIOT and A and F line to SIGILL
	   We will need to fix up 68000 v 68010 move to/from SR */
	static const uint8_t trap_to_sig[] = {
		0, 0, SIGSEGV, SIGBUS, SIGILL, SIGFPE,
		SIGABRT/*CHK*/, SIGTRAP/*TRAPV */,
		SIGILL, SIGIOT, SIGILL, SIGFPE };

	proc = udata.u_ptab;

	if (sysinfo.cpu[0] == 10) {
		/* Long or short frame: the CPU tells us the frame format */
		if (framedata->exception[3] & 0x8000) {
			fsize = 29;
			frame = FRAME_C;
		} else  {
			fsize = 4;
			frame = FRAME_D;
		}
	} else {
		frame = FRAME_B;
		fsize = 3;
	}
	if (trap == 0) {
		sig = udata.u_cursig;
		udata.u_cursig = 0;
	} else if (trap < 12) {
		if (trap < 4) {
			/* On a 68010 this frame is 29 words and the event is
			   restartable (although not always usefully). We need to
			   decide whether to set the restart flag case by case */
			if (sysinfo.cpu[0] == 0) {
				frame = FRAME_A;
				fsize = 7;
			}
		}
		sig = trap_to_sig[trap];
	} else if (trap >= 32 && trap < 48)
		sig = SIGTRAP;
	/* This processing only applies to synchronous hardware exceptions */
	if (trap) {
		/* Went boom in kernel space or without a user recovery */
		if (kernel_flag || sig == 0) {
			explode(framedata, frame);
			panic("trap");
		}

		/* Cheating here .. all our exceptions are low 16 signal */
		m = 1 << sig;
		/*
		 *	The caller is ignoring our signal. In some cases this is fine
		 *	but in others it's less clear (eg division by zero) and we
		 *	may need to take different action.
		 */
		if (proc->p_sig[0].s_ignored & m)
			return 0;
		/* Weird case - we took a sync signal and the caller wants us to
		   report it later. */
		if (proc->p_sig[0].s_held & m) {
			/* TODO: if it's not meaningfully restartable we should
			   probably treat this as a kill */
			ssig(proc, sig);
			return 0;
		}
		recalc_cursig();	/* Put any async signal back */
	}
	if (udata.u_sigvec[sig] == SIG_DFL) {
		/* Default action for our signal ? */
		doexit(dump_core(sig));
		/* This will never return. We will go schedule new work */
		panic("exret");
	}
	/* build signal frame

		Our unwinder code does
		move.l 8(sp),sp
		movem.l a0-a1/d0-d1,(sp)+
		move.w (sp)+,ccr
		rts */


	/* Now update the user stack */
	/* - Push the recovery PC */
	/* - Patch the kernel exception frame */
	if (sysinfo.cpu[0]) {
		/* FIXME */
		err |= pushw(&usp, sp[34]);
		err |= pushw(&usp, sp[33]);
		*(uint32_t *)(&sp[33]) = (uint32_t)udata.u_sigvec[sig];
	} else {
		err |= pushw(&usp, sp[31 + fsize]);
		err |= pushw(&usp, sp[30 + fsize]);
		*(uint32_t *)(&sp[30 + fsize]) = (uint32_t)udata.u_sigvec[sig];
	}

	/* FIXME: when we do ptrace we will need to support adding the T
	   flag back here as the exception cleared it */
	err |= pushw(&usp,  framedata->sr);
	/* Push A1 A0 D1 D0 to match MOVEM.L */
	err |= pushl(&usp, framedata->a[1]);
	err |= pushl(&usp, framedata->a[0]);
	err |= pushl(&usp, framedata->d[1]);
	err |= pushl(&usp, framedata->d[0]);

	/* Remember the target for undoing the frame */
	unwind = usp;

	/* Copy in the signal context itself. 30 words of registers, 2 of
	   trap code and then the hardware exception */
	for (i = 0; i < 30 + 2 + fsize; i++)
		err |= pushw(&usp, *sp++);
	context = usp;
	err |= pushl(&usp, (uint32_t)unwind);
	/* Signal context is a secret extra non portable argument */
	err |= pushl(&usp, (uint32_t)context);
	/* We end it with the call frame as seen from the signal handler, a
	   single argument and a return address */
	err |= pushl(&usp, sig);
	err |= pushl(&usp, udata.u_codebase + 0x04);

	set_usp(usp);

	if (err) {
		doexit(dump_core(SIGSTKFLT));
		panic("exret2");
	}
	/* Once built clear the restart state */
	udata.u_sigvec[sig] = SIG_DFL;
	/* Return, RTE and end up on the signal frame */
	return 1;
}
Example #10
0
static void exit_server_common(enum server_exit_reason how,
	const char *const reason)
{
	struct smbd_server_connection *sconn = smbd_server_conn;

	if (!exit_firsttime)
		exit(0);
	exit_firsttime = false;

	change_to_root_user();

	if (sconn && sconn->smb1.negprot.auth_context) {
		TALLOC_FREE(sconn->smb1.negprot.auth_context);
	}

	if (sconn) {
		if (lp_log_writeable_files_on_exit()) {
			bool found = false;
			files_forall(sconn, log_writeable_file_fn, &found);
		}
		(void)conn_close_all(sconn);
		invalidate_all_vuids(sconn);
	}

	/* 3 second timeout. */
	print_notify_send_messages(sconn->msg_ctx, 3);

	/* delete our entry in the serverid database. */
	if (am_parent) {
		/*
		 * For children the parent takes care of cleaning up
		 */
		serverid_deregister(sconn_server_id(sconn));
	}

#ifdef WITH_DFS
	if (dcelogin_atmost_once) {
		dfs_unlogin();
	}
#endif

#ifdef USE_DMAPI
	/* Destroy Samba DMAPI session only if we are master smbd process */
	if (am_parent) {
		if (!dmapi_destroy_session()) {
			DEBUG(0,("Unable to close Samba DMAPI session\n"));
		}
	}
#endif

	if (am_parent) {
		rpc_wkssvc_shutdown();
#ifdef ACTIVE_DIRECTORY
		rpc_dssetup_shutdown();
#endif
#ifdef DEVELOPER
		rpc_rpcecho_shutdown();
#endif
#ifdef DFS_SUPPORT
		rpc_netdfs_shutdown();
#endif
		rpc_initshutdown_shutdown();
#ifdef EXTRA_SERVICES
		rpc_eventlog_shutdown();
		rpc_svcctl_shutdown();
		rpc_ntsvcs_shutdown();
#endif
#ifdef PRINTER_SUPPORT
		rpc_spoolss_shutdown();
#endif

		rpc_srvsvc_shutdown();
#ifdef WINREG_SUPPORT
		rpc_winreg_shutdown();
#endif

#ifdef NETLOGON_SUPPORT
		rpc_netlogon_shutdown();
#endif
#ifdef SAMR_SUPPORT
		rpc_samr_shutdown();
#endif
#ifdef LSA_SUPPORT
		rpc_lsarpc_shutdown();
#endif
	}

	/*
	 * we need to force the order of freeing the following,
	 * because smbd_msg_ctx is not a talloc child of smbd_server_conn.
	 */
	sconn = NULL;
	TALLOC_FREE(smbd_server_conn);
	server_messaging_context_free();
	server_event_context_free();
	TALLOC_FREE(smbd_memcache_ctx);

	locking_end();
	printing_end();

	if (how != SERVER_EXIT_NORMAL) {
		DEBUGSEP(0);
		DEBUG(0,("Abnormal server exit: %s\n",
			reason ? reason : "no explanation provided"));
		DEBUGSEP(0);

		log_stack_trace();

		dump_core();

		/* Notreached. */
		exit(1);
	} else {
		DEBUG(3,("Server exit (%s)\n",
			(reason ? reason : "normal exit")));
		if (am_parent) {
			pidfile_unlink();
		}
		gencache_stabilize();
	}

	exit(0);
}
Example #11
0
static void exit_server_common(enum server_exit_reason how,
	const char *const reason)
{
	static int firsttime=1;

	if (!firsttime) {
#ifndef _XBOX
		exit(0);
#endif
	}
	firsttime = 0;

	change_to_root_user();

	if (negprot_global_auth_context) {
		(negprot_global_auth_context->free)(&negprot_global_auth_context);
	}

	conn_close_all();

	invalidate_all_vuids();
#ifndef _XBOX
	print_notify_send_messages(3); /* 3 second timeout. */
#endif
	/* delete our entry in the connections database. */
	yield_connection(NULL,"");

	respond_to_all_remaining_local_messages();
	decrement_smbd_process_count();

#ifdef WITH_DFS
	if (dcelogin_atmost_once) {
		dfs_unlogin();
	}
#endif

#ifndef _XBOX
	locking_end();
	printing_end();
#endif

	if (how != SERVER_EXIT_NORMAL) {
		int oldlevel = DEBUGLEVEL;
		char *last_inbuf = get_InBuffer();

		DEBUGLEVEL = 10;

		DEBUGSEP(0);
		DEBUG(0,("Abnormal server exit: %s\n",
			reason ? reason : "no explanation provided"));
		DEBUGSEP(0);

#ifndef _XBOX
		log_stack_trace();
#endif
		if (last_inbuf) {
			DEBUG(0,("Last message was %s\n", LAST_MESSAGE()));
			show_msg(last_inbuf);
		}

		DEBUGLEVEL = oldlevel;
#if DUMP_CORE
		dump_core();
#endif

	} else {    
		DEBUG(3,("Server exit (%s)\n",
			(reason ? reason : "normal exit")));
	}

#ifndef _XBOX
	exit(0);
#endif
}