在C中,不能改变结构属性,除非使用#define VAL [英] In C, can't change a struct attribute except using #define val
问题描述
在Minix的3.1.2a我有一个结构 proc结构
,其中存储的任何过程的PCB,
但我增加新的属性时,已经有问题 p_currenthash
在下面这个结构中的code。我无法改变它的价值除了利用的#define
指令定义的常数;否则,系统停止响应。为清楚起见这里是结构:
proc结构{
结构stackframe_s p_reg; / *进程的寄存器保存在栈帧* /#如果(CHIP == INTEL)
reg_t p_ldt_sel; / *选择与LDT基址和限制GDT * /
结构segdesc_s p_ldt [2 + NR_REMOTE_SEGS]; / * CS,DS和远程段* /
#万一#如果(CHIP == M68000)
/ * M68000的特定的寄存器和FPU详情,请点击这里。 * /
#万一 proc_nr_t p_nr; / *这个过程的数目(对于快速接入)* /
结构私法* p_priv; / *系统权限结构* /
短p_rts_flags; / *过程是可运行的只有零* /
短p_misc_flags; / *标志是做暂停处理* / 焦炭p_priority; / *当前调度优先级* /
焦炭p_max_priority; / *最大调度优先级* /
焦炭p_ticks_left; / *调度的周期数左* /
焦炭p_quantum_size; / *量子尺寸蜱* / 结构mem_map中p_memmap [NR_LOCAL_SEGS] / *内存映射(T,D,S)* / clock_t表示p_user_time; / *用户时间刻度* /
clock_t表示p_sys_time; / * SYS时间刻度* / proc结构* p_nextready; / *指向下一个准备过程* /
proc结构* p_caller_q; / *希望发送特效列表头* /
proc结构* p_q_link; / *链接到下PROC希望发送* /
消息* p_messbuf; / *指针传递消息缓冲区* /
INT p_getfrom_e; / *从谁不希望过程接受? * /
INT p_sendto_e; / *谁也处理要发送? * / sigset_t p_pending; / *位图待处理内核信号* / 焦炭p_name [P_NAME_LEN] / *方法的名称,包括\\ 0 * / INT p_endpoint; / *端点号,一代感知* /#如果DEBUG_SCHED_CHECK
INT p_ready,p_found;
#万一 焦炭p_currenthash; / * *散列/};
现在,假设我要设置其值。起初,我使用下面定义的常量。
的#define NONE -1注册proc结构* RP;RP-GT&; p_currenthash =无;
这工作得很好,但这: RP-GT&; p_currenthash = 0;
将导致程序停止响应
任何建议将AP preciated
下面是主初始化的main()
:
/ *启动球滚动。 * /
结构BOOT_IMAGE * IP; / *启动映像指针* /
注册proc结构* RP; / *过程指针* /
注册结构私法* SP; / *特权结构指针* /
注册INT I,S;
INT hdrindex; / *指数的a.out头阵列* /
phys_clicks TEXT_BASE;
vir_clicks text_clicks,data_clicks;
reg_t ktsb; / *内核任务堆栈基地* /
结构EXEC e_hdr; / *为out的头部的拷贝* / / *初始化中断控制器。 * /
intr_init(1); / *清除进程表。 Anounce每个插槽为空,设置映射
*为proc_addr()和proc_nr()宏。做同样的表
*作系统进程权限的结构。
* /
对(RP = BEG_PROC_ADDR,I = -NR_TASKS; RP< END_PROC_ADDR ++ RP,我++){
RP-GT&; p_rts_flags = SLOT_FREE; / *初始化免费插槽* /
RP-GT&; p_nr = I; / * PROC从PTR数* / RP-GT&; p_currenthash =无; RP-GT&; p_endpoint = _ENDPOINT(0,RP-GT&; p_nr); / *一代没有。 0 * / (pproc_addr + NR_TASKS)[I] = RP; / * PROC从数PTR * /
}
对于(SP = BEG_PRIV_ADDR,I = 0;的sp LT; END_PRIV_ADDR ++ SP,我++){
SP-GT&; s_proc_nr =无; / *初始化免费* /
SP-GT&; S_ID = I; / *私法结构指数* /
ppriv_addr [I] = SP; / *私法从数量PTR * /
} / *设置PROC表项为引导映像过程。的堆栈
*内核任务被初始化为在数据空间阵列。书库
的服务器*已被添加到由监视数据段,所以
*堆栈指针被设置到数据段的结束。一切
*过程是在低内存的8086在386只内核
*在低内存,剩下的就是在扩展内存中加载。
* / / *任务堆栈。 * /
ktsb =(reg_t)t_stack; 对于(i = 0; I< NR_BOOT_PROCS ++我){
IP =&放大器;图片[I]; / *进程的属性* /
RP = proc_addr(IP-> proc_nr); / *获取进程的指针* /
IP->终点= RP-GT&; p_endpoint; / * IPC端点* /
RP-GT&; p_max_priority = IP->优先; / *最大调度优先级* /
RP-GT&; p_priority = IP->优先; / *当前优先* /
RP-GT&; p_quantum_size = IP->量子; / *量子尺寸蜱* /
RP-GT&; p_ticks_left = IP->量子; / *当前的信贷* /
函数strncpy(RP-GT&; p_name,IP-> proc_name中,P_NAME_LEN); / *设置进程名* /
(无效)get_priv(RP(IP->旗帜与放大器; SYS_PROC)); / *分配结构* /
私法(RP) - GT; s_flags = IP->标志; / *进程标志* /
私法(RP) - GT; s_trap_mask = IP-> trap_mask; / *允许的陷阱* /
私法(RP) - GT; s_call_mask = IP-> call_mask; / *内核调用面具* /
PRIV(RP) - > s_ipc_to.chunk [0] = IP-> ipc_to; / *限制目标* /
如果(iskerneln(proc_nr(RP))){/ *内核的一部分? * /
如果(IP-> stksize大于0){/ *硬件堆栈大小为0 * /
RP-GT&;&p_priv- GT; s_stack_guard =(reg_t *)ktsb;
* RP-GT&;&p_priv- GT; s_stack_guard = STACK_GUARD;
}
ktsb + = IP-> stksize; / *指向堆栈的高端* /
RP-GT&; p_reg.sp = ktsb; / *这个任务的初始堆栈PTR * /
TEXT_BASE = kinfo code_base方式>> CLICK_SHIFT;
/ *过程是在内核* /
hdrindex = 0; / *所有使用第一个a.out头部* /
}其他{
hdrindex = 1 + I-NR_TASKS; / *服务器,驱动程序,INIT * /
} / *引导加载程序创建的a.out的头的数组在
*绝对地址AOUT。获取一个元素e_hdr。
* /
phys_copy(AOUT + hdrindex * A_MINHDR,vir2phys(安培; e_hdr)
(phys_bytes)A_MINHDR);
/ *转换地址的点击和建设进程的内存映射* /
TEXT_BASE = e_hdr.a_syms>> CLICK_SHIFT;
text_clicks =(e_hdr.a_text + CLICK_SIZE-1)GT;> CLICK_SHIFT;
如果((e_hdr.a_flags&放大器;!A_SEP))text_clicks = 0; / *通用的I和D * /
data_clicks =(e_hdr.a_total + CLICK_SIZE-1)GT;> CLICK_SHIFT;
RP-GT&; p_memmap [T] .mem_phys = TEXT_BASE;
RP-GT&; p_memmap [T] .mem_len = text_clicks;
RP-GT&; p_memmap研究[D] .mem_phys = TEXT_BASE + text_clicks;
RP-GT&; p_memmap研究[D] .mem_len = data_clicks;
RP-GT&; p_memmap [S] .mem_phys = TEXT_BASE + text_clicks + data_clicks;
RP-GT&; p_memmap [S] .mem_vir = data_clicks; / *空 - 堆栈数据* / / *设置初始寄存器值。对于任务的处理器状态字
*是来自其他进程的不同,因为任务可以
*访问I / O;这是不允许的,以较低权限的进程
* /
RP-GT&; p_reg.pc =(reg_t)IP-GT&; initial_pc;
RP-GT&; p_reg.psw =(iskernelp(RP))? INIT_TASK_PSW:INIT_PSW; / *初始化服务器堆栈指针。把它记下来一个字
*给crtso.s的东西为ARGC来使用。
* /
如果(isusern(proc_nr(RP))){/ *用户空间进程? * /
RP-GT&; p_reg.sp =(RP-GT&; p_memmap [S] .mem_vir +
RP-GT&; p_memmap [S] .mem_len)LT;< CLICK_SHIFT;
RP-GT&; p_reg.sp - = sizeof的(reg_t);
} / *设置就绪。硬件任务是从来没有准备好。 * /
如果(RP-GT&; p_nr =硬件!){
RP-> p_rts_flags = 0; / *可运行的,如果没有标志* /
lock_enqueue(RP); / *添加到调度的队列* /
}其他{
RP-GT&; p_rts_flags = NO_MAP;从运行/ * prevent * /
} / * code和数据段必须在保护模式下进行分配。 * /
alloc_segments(RP);
}
注册proc结构* RP;RP-GT&; p_currenthash =无;
RP
是一个未初始化的指针;它不是指向一个有效的 proc结构
对象,所以取消引用它导致的未定义行为的。即当分配给这没有崩溃的事实是-1运气纯正。 (运气不好,因为它误导了你要相信你在做一些有意义的事情)
In Minix 3.1.2a I've a struct "struct proc
" where the PCB of any process stored,
but I've a problem when adding new attribute "p_currenthash
" in the code below to this struct. I can't change its value except using a constant defined by #define
directive; otherwise, the system stops responding. For clarity here is the structure:
struct proc {
struct stackframe_s p_reg; /* process' registers saved in stack frame */
#if (CHIP == INTEL)
reg_t p_ldt_sel; /* selector in gdt with ldt base and limit */
struct segdesc_s p_ldt[2+NR_REMOTE_SEGS]; /* CS, DS and remote segments */
#endif
#if (CHIP == M68000)
/* M68000 specific registers and FPU details go here. */
#endif
proc_nr_t p_nr; /* number of this process (for fast access) */
struct priv *p_priv; /* system privileges structure */
short p_rts_flags; /* process is runnable only if zero */
short p_misc_flags; /* flags that do suspend the process */
char p_priority; /* current scheduling priority */
char p_max_priority; /* maximum scheduling priority */
char p_ticks_left; /* number of scheduling ticks left */
char p_quantum_size; /* quantum size in ticks */
struct mem_map p_memmap[NR_LOCAL_SEGS]; /* memory map (T, D, S) */
clock_t p_user_time; /* user time in ticks */
clock_t p_sys_time; /* sys time in ticks */
struct proc *p_nextready; /* pointer to next ready process */
struct proc *p_caller_q; /* head of list of procs wishing to send */
struct proc *p_q_link; /* link to next proc wishing to send */
message *p_messbuf; /* pointer to passed message buffer */
int p_getfrom_e; /* from whom does process want to receive? */
int p_sendto_e; /* to whom does process want to send? */
sigset_t p_pending; /* bit map for pending kernel signals */
char p_name[P_NAME_LEN]; /* name of the process, including \0 */
int p_endpoint; /* endpoint number, generation-aware */
#if DEBUG_SCHED_CHECK
int p_ready, p_found;
#endif
char p_currenthash; /* hash */
};
Now, suppose I want to set its value. Initially I use the constant defined below.
#define NONE -1
register struct proc *rp;
rp->p_currenthash=NONE;
That works fine, but this: rp->p_currenthash=0 ;
will cause the program to stop responding.
Any suggestions will be appreciated
Here's the main initialization in main()
:
/* Start the ball rolling. */
struct boot_image *ip; /* boot image pointer */
register struct proc *rp; /* process pointer */
register struct priv *sp; /* privilege structure pointer */
register int i, s;
int hdrindex; /* index to array of a.out headers */
phys_clicks text_base;
vir_clicks text_clicks, data_clicks;
reg_t ktsb; /* kernel task stack base */
struct exec e_hdr; /* for a copy of an a.out header */
/* Initialize the interrupt controller. */
intr_init(1);
/* Clear the process table. Anounce each slot as empty and set up mappings
* for proc_addr() and proc_nr() macros. Do the same for the table with
* privilege structures for the system processes.
*/
for (rp = BEG_PROC_ADDR, i = -NR_TASKS; rp < END_PROC_ADDR; ++rp, ++i) {
rp->p_rts_flags = SLOT_FREE; /* initialize free slot */
rp->p_nr = i; /* proc number from ptr */
rp->p_currenthash=NONE;
rp->p_endpoint = _ENDPOINT(0, rp->p_nr); /* generation no. 0 */
(pproc_addr + NR_TASKS)[i] = rp; /* proc ptr from number */
}
for (sp = BEG_PRIV_ADDR, i = 0; sp < END_PRIV_ADDR; ++sp, ++i) {
sp->s_proc_nr = NONE; /* initialize as free */
sp->s_id = i; /* priv structure index */
ppriv_addr[i] = sp; /* priv ptr from number */
}
/* Set up proc table entries for processes in boot image. The stacks of the
* kernel tasks are initialized to an array in data space. The stacks
* of the servers have been added to the data segment by the monitor, so
* the stack pointer is set to the end of the data segment. All the
* processes are in low memory on the 8086. On the 386 only the kernel
* is in low memory, the rest is loaded in extended memory.
*/
/* Task stacks. */
ktsb = (reg_t) t_stack;
for (i=0; i < NR_BOOT_PROCS; ++i) {
ip = &image[i]; /* process' attributes */
rp = proc_addr(ip->proc_nr); /* get process pointer */
ip->endpoint = rp->p_endpoint; /* ipc endpoint */
rp->p_max_priority = ip->priority; /* max scheduling priority */
rp->p_priority = ip->priority; /* current priority */
rp->p_quantum_size = ip->quantum; /* quantum size in ticks */
rp->p_ticks_left = ip->quantum; /* current credit */
strncpy(rp->p_name, ip->proc_name, P_NAME_LEN); /* set process name */
(void) get_priv(rp, (ip->flags & SYS_PROC)); /* assign structure */
priv(rp)->s_flags = ip->flags; /* process flags */
priv(rp)->s_trap_mask = ip->trap_mask; /* allowed traps */
priv(rp)->s_call_mask = ip->call_mask; /* kernel call mask */
priv(rp)->s_ipc_to.chunk[0] = ip->ipc_to; /* restrict targets */
if (iskerneln(proc_nr(rp))) { /* part of the kernel? */
if (ip->stksize > 0) { /* HARDWARE stack size is 0 */
rp->p_priv->s_stack_guard = (reg_t *) ktsb;
*rp->p_priv->s_stack_guard = STACK_GUARD;
}
ktsb += ip->stksize; /* point to high end of stack */
rp->p_reg.sp = ktsb; /* this task's initial stack ptr */
text_base = kinfo.code_base >> CLICK_SHIFT;
/* processes that are in the kernel */
hdrindex = 0; /* all use the first a.out header */
} else {
hdrindex = 1 + i-NR_TASKS; /* servers, drivers, INIT */
}
/* The bootstrap loader created an array of the a.out headers at
* absolute address 'aout'. Get one element to e_hdr.
*/
phys_copy(aout + hdrindex * A_MINHDR, vir2phys(&e_hdr),
(phys_bytes) A_MINHDR);
/* Convert addresses to clicks and build process memory map */
text_base = e_hdr.a_syms >> CLICK_SHIFT;
text_clicks = (e_hdr.a_text + CLICK_SIZE-1) >> CLICK_SHIFT;
if (!(e_hdr.a_flags & A_SEP)) text_clicks = 0; /* common I&D */
data_clicks = (e_hdr.a_total + CLICK_SIZE-1) >> CLICK_SHIFT;
rp->p_memmap[T].mem_phys = text_base;
rp->p_memmap[T].mem_len = text_clicks;
rp->p_memmap[D].mem_phys = text_base + text_clicks;
rp->p_memmap[D].mem_len = data_clicks;
rp->p_memmap[S].mem_phys = text_base + text_clicks + data_clicks;
rp->p_memmap[S].mem_vir = data_clicks; /* empty - stack is in data */
/* Set initial register values. The processor status word for tasks
* is different from that of other processes because tasks can
* access I/O; this is not allowed to less-privileged processes
*/
rp->p_reg.pc = (reg_t) ip->initial_pc;
rp->p_reg.psw = (iskernelp(rp)) ? INIT_TASK_PSW : INIT_PSW;
/* Initialize the server stack pointer. Take it down one word
* to give crtso.s something to use as "argc".
*/
if (isusern(proc_nr(rp))) { /* user-space process? */
rp->p_reg.sp = (rp->p_memmap[S].mem_vir +
rp->p_memmap[S].mem_len) << CLICK_SHIFT;
rp->p_reg.sp -= sizeof(reg_t);
}
/* Set ready. The HARDWARE task is never ready. */
if (rp->p_nr != HARDWARE) {
rp->p_rts_flags = 0; /* runnable if no flags */
lock_enqueue(rp); /* add to scheduling queues */
} else {
rp->p_rts_flags = NO_MAP; /* prevent from running */
}
/* Code and data segments must be allocated in protected mode. */
alloc_segments(rp);
}
register struct proc *rp;
rp->p_currenthash=NONE;
rp
is an uninitialized pointer; it isn't pointing to a valid struct proc
object, and so dereferencing it leads to undefined behavior. The fact that this didn't crash when assigning -1 was pure luck. (bad luck, because it misled you to believe you were doing something meaningful)
这篇关于在C中,不能改变结构属性,除非使用#define VAL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!