我明白,用户可以拥有一个进程,每个进程有一个地址空间(其中包含有效的内存位置,这个过程可以参考)。 我知道一个进程可以调用系统调用并将parameter passing给它,就像任何其他库函数一样。 这似乎表明,所有的系统调用都是通过共享内存等方式进入进程地址空间的。但也许,这只是一个错觉,因为在高级编程语言中,系统调用看起来像任何其他函数,当一个进程调用它。 但是,现在让我进一步深入分析一下底下发生了什么。 编译器如何编译系统调用? 它可能会将进程提供的系统调用名称和参数压入堆栈,然后将汇编指令称为“TRAP”或其他东西 – 基本上就是调用软件中断的汇编指令。 该TRAP汇编指令由硬件执行,首先将模式位从用户切换到内核,然后将代码指针设置为开始中断服务例程。 从这一点开始,ISR以内核模式执行,从堆栈中获取参数(这是可能的,因为内核可以访问任何内存位置,甚至是用户进程拥有的内存位置),并执行系统调用结束放弃CPU,再次切换模式位,用户进程从停止的地方开始。 我的理解是正确的吗? 附上的是我的理解粗略的图表:
我需要在我的网站上编译和运行用户提交的脚本,类似于键盘和ideone 。 我怎样才能沙盒这些程序,使恶意用户不会把我的服务器? 具体来说,我想locking在一个空目录内,防止他们读取或写入任何地方,消耗太多的内存或CPU,或从其他任何恶意的东西。 我将需要通过沙箱外部的pipe道(通过stdin / stdout)与这些程序进行通信。
我研究了Linux内核,发现对于x86_64体系结构来说,中断int 0x80不起调用系统调用的作用。 问题是:在x86架构的情况下什么是更可取的syscall或int 0x80 ,为什么? 编辑 :我使用内核3.4
我已经知道真正的用户ID。 这是系统中用户的唯一号码。 在我的系统中,我的uid是 $ echo $UID 1014 $ 另外两个ID代表什么? 什么是有效的用户ID和保存的用户ID和我们在系统中使用它的用途。
我可以使用什么来调用操作系统在用户默认的浏览器中打开一个URL? 不担心跨OS兼容性; 如果它在linux下工作对我来说足够了!
我可以理解如何编写一个使用多个进程或线程的程序:fork()一个新进程并使用IPC,或者创build多个线程并使用这些types的通信机制。 我也理解上下文切换。 也就是说,只有一个CPU,操作系统为每个进程安排时间(并且有大量的调度algorithm在那里),从而实现同时运行多个进程。 而现在我们有了多核处理器(或者多处理器的计算机),我们可以在两个独立的内核上同时运行两个进程。 我的问题是关于最后的情况:内核如何控制一个进程运行的核心? 哪些系统调用(在Linux甚至Windows中)在特定内核上调度进程? 我问这个问题的原因是:我正在为一个项目寻找计算方面的最新课题 – 我select了多核架构。 在如何在这种环境下编程(如何监视死锁或竞赛状况)似乎有很多材料,但在控制单个核心本身方面却没有太多的材料。 我希望能够编写一些演示程序,并给出一些汇编指令或C代码,以便大意:“看,我在第二个内核上运行一个无限循环,查看特定内核的 CPU利用率高峰” 。 任何代码示例? 还是教程? 编辑:澄清 – 很多人都说这是操作系统的目的,而且应该让操作系统照顾这个。 我完全同意! 但是,我所要求的(或试图去感受)是操作系统实际做到的。 不是调度algorithm,而是更多“一旦核心被选中,必须执行什么指令才能让核心开始获取指令?
Linux编程接口在第3章中有一个练习: 当使用Linux特有的reboot()系统调用来重启系统时,第二个参数magic2必须被指定为一组幻数(例如,LINUX_REBOOT_MAGIC2)。 这些数字的意义是什么? (将它们转换为hex提供了一个线索。) 手册页告诉我们magic2可以是LINUX_REBOOT_MAGIC2(672274793),LINUX_REBOOT_MAGIC2A(85072278),LINUX_REBOOT_MAGIC2B(369367448)或LINUX_REBOOT_MAGIC2C(537993216)之一。 我没有用hex解释他们的意思。 我也看了/usr/include/linux/reboot.h ,也没有给出任何有用的评论。 然后我在内核的源代码中search了sys_reboot的定义。 我发现的只是一个头文件中的声明。 所以,我的第一个问题是,这些数字的意义是什么? 我的第二个问题是, sys_reboot的定义在哪里,你是怎么find它的? 编辑 :我发现kernel/sys.c的定义。 我只grepped为sys_reboot ,忘了grep的MAGIC号码。 我觉得这个定义必须隐藏在一些macros观把戏后面,所以我查看了/boot下的System.map文件,并在ctrl_alt_del旁边find了它。 然后,我为那个符号擦了擦,这导致了我正确的文件。 如果我从源代码编译内核,我可以尝试find哪个目标文件定义了符号,然后从那里开始。
我想写一个信号处理程序来捕获SIGSEGV。 我保护一块内存以供读取或写入使用 char *buffer; char *p; char a; int pagesize = 4096; mprotect(buffer,pagesize,PROT_NONE) 这可以保护从缓冲区开始的页面缓冲区的任何读写操作。 其次,我尝试阅读记忆: p = buffer; a = *p 这将生成一个SIGSEGV,我的处理程序将被调用。 到现在为止还挺好。 我的问题是,一旦处理程序被调用,我想通过做改变访问写入的内存 mprotect(buffer,pagesize,PROT_READ); 并继续我的代码正常运作。 我不想退出这个function。 在未来写入相同的内存,我想再次捕捉信号,并修改写权限,然后logging该事件。 这里是代码 : #include <signal.h> #include <stdio.h> #include <malloc.h> #include <stdlib.h> #include <errno.h> #include <sys/mman.h> #define handle_error(msg) \ do { perror(msg); exit(EXIT_FAILURE); } while (0) char *buffer; int […]
我想了解使用dup2和dup 。 从手册页: DESCRIPTION dup and dup2 create a copy of the file descriptor oldfd. After successful return of dup or dup2, the old and new descriptors may be used interchangeably. They share locks, file position pointers and flags; for example, if the file position is modified by using lseek on one of the descriptors, […]
根据Linux程序员手册: brk()和sbrk()改变程序中断的位置,它定义了进程数据段的结束。 数据段在这里意味着什么? 它只是数据段或数据,BSS和堆的组合? 根据维基: 有时数据,BSS和堆区被统称为“数据段”。 我没有理由改变数据段的大小。 如果是数据,BSS和堆集体然后它是有道理的,因为堆将获得更多的空间。 这使我想到了第二个问题。 在我读到的所有文章中,作者说堆积向上,堆积向下。 但是他们没有解释的是,当堆占用堆栈之间的所有空间时会发生什么?