Calls with a Variable Number of Arguments

本文介绍了C语言中可变参数函数的相关知识。可变参数列表可用省略号表示,至少一个参数要在省略号前,且省略号须为参数列表最后一个标记。调用时可指定任意数量参数,参数会入栈。还提及了访问可变参数的宏,以及微软对ANSI C标准的扩展。

From: C Language Reference (Visual C++ .NET)

A partial parameter list can be terminated by the ellipsis notation, a comma followed by three periods (, ...), to indicate that there may be more arguments passed to the function, but no more information is given about them. Type checking is not performed on such arguments. At least one parameter must precede the ellipsis notation and the ellipsis notation must be the last token in the parameter list. Without the ellipsis notation, the behavior of a function is undefined if it receives parameters in addition to those declared in the parameter list.

To call a function with a variable number of arguments, simply specify any number of arguments in the function call. An example is the printf function from the C run-time library. The function call must include one argument for each type name declared in the parameter list or the list of argument types.

All the arguments specified in the function call are placed on the stack unless the __fastcall calling convention is specified. The number of parameters declared for the function determines how many of the arguments are taken from the stack and assigned to the parameters. You are responsible for retrieving any additional arguments from the stack and for determining how many arguments are present. The STDARG.H file contains ANSI-style macros for accessing arguments of functions which take a variable number of arguments. Also, the XENIX?- style macros in VARARGS.H are still supported.

This sample declaration is for a function that calls a variable number of arguments:

int average( int first, ...);
Microsoft Specific —>

To maintain compatibility with previous versions of Microsoft C, a Microsoft extension to the ANSI C standard allows a comma without trailing periods (,) at the end of the list of parameters to indicate a variable number of arguments. However, it is recommended that code be changed to incorporate the ellipsis notation.

END Microsoft Specific

现在我在完成xv6相关实验,请根据实验指南给我详细的实验指导,具体到每一个步骤,以下是实验指南: System call tracing (moderate) In this assignment you will add a system call tracing feature that may help you when debugging later labs. You'll create a new trace system call that will control tracing. It should take one argument, an integer "mask", whose bits specify which system calls to trace. For example, to trace the fork system call, a program calls trace(1 << SYS_fork), where SYS_fork is a syscall number from kernel/syscall.h. You have to modify the xv6 kernel to print out a line when each system call is about to return, if the system call's number is set in the mask. The line should contain the process id, the name of the system call and the return value; the number of times the system call is traced; you don't need to print the system call arguments. The trace system call should enable tracing for the process that calls it and any children that it subsequently forks, but should not affect other processes. We provide a trace user-level program that runs another program with tracing enabled (see user/trace.c). When you're done, you should see output like this: $ trace 32 grep hello README 3: syscall read(trace counts: 1) -> 1023 3: syscall read(trace counts: 2) -> 961 3: syscall read(trace counts: 3) -> 321 3: syscall read(trace counts: 4) -> 0 $ $ trace 2147483647 grep hello README 5: syscall trace(trace counts: 1) -> 0 5: syscall exec(trace counts: 1) -> 3 5: syscall open(trace counts: 1) -> 3 5: syscall read(trace counts: 5) -> 1023 5: syscall read(trace counts: 6) -> 961 5: syscall read(trace counts: 7) -> 321 5: syscall read(trace counts: 8) -> 0 5: syscall close(trace counts: 1) -> 0 $ $ grep hello README $ $ trace 2 usertests forkforkfork usertests starting 9: syscall fork(trace counts: 1) -> 10 test forkforkfork: 9: syscall fork(trace counts: 2) -> 11 11: syscall fork(trace counts: 3) -> 12 12: syscall fork(trace counts: 4) -> 13 12: syscall fork(trace counts: 5) -> 14 13: syscall fork(trace counts: 6) -> 15 ... $ In the first example above, trace invokes grep tracing just the read system call. The 32 is 1<<SYS_read. In the second example, trace runs grep while tracing all system calls; the 2147483647 has all 31 low bits set. In the third example, the program isn't traced, so no trace output is printed. In the fourth example, the fork system calls of all the descendants of the forkforkfork test in usertests are being traced. Your solution is correct if your program behaves as shown above (though the process IDs may be different). Meanwhile, all of these examples show how many times these system calls were traced. Some hints: Add $U/_trace to UPROGS in Makefile Run and you will see that the compiler cannot compile user/trace.c, because the user-space stubs for the system call don't exist yet: add a prototype for the system call to user/user.h, a stub to user/usys.pl, and a syscall number to kernel/syscall.h. The Makefile invokes the perl script user/usys.pl, which produces user/usys.S, the actual system call stubs, which use the RISC-V ecall instruction to transition to the kernel. Once you fix the compilation issues, run ; it will fail because you haven't implemented the system call in the kernel yet. make qemutrace 32 grep hello README Add a sys_trace() function in kernel/sysproc.c that implements the new system call by remembering its argument in a new variable in the proc structure (see kernel/proc.h). The functions to retrieve system call arguments from user space are in kernel/syscall.c, and you can see examples of their use in kernel/sysproc.c. Modify fork() (see kernel/proc.c) to copy the trace mask from the parent to the child process. Modify the syscall() function in kernel/syscall.c to print the trace output. You will need to add an array of syscall names to index into. You may need to add an array in kernel/syscall.c to count the number of times the system call is traced. If a test case passes when you run it inside qemu directly but you get a timeout when running the tests using make grade, try testing your implementation on Athena. Some of tests in this lab can be a bit too computationally intensive for your local machine (especially if you use WSL).
11-22
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值