无法理解读取系统调用的行为

发布于 2024-10-15 08:28:02 字数 1110 浏览 9 评论 0原文

所以这是我试图运行的代码:

#include<fcntl.h>
#include<stdio.h>
#include<errno.h>
#include<string.h>
#include<unistd.h>

int main(){

  int ret;

  ret = read(STDIN_FILENO,(int*)2000,3);
  printf("%d--%s\n",ret,strerror(errno));

  return 0;
}

这是我在终端得到的输出

anirudh@anirudh-Aspire-5920:~/Desktop/testing$ gcc test.c 
anirudh@anirudh-Aspire-5920:~/Desktop/testing$ ./a.out 
lls
-1--Bad address
anirudh@anirudh-Aspire-5920:~/Desktop/testing$ ls
a.out  htmlget_ori.c  mysocket.cpp  Packet Sniffer.c  resolutionfinder.c  test.c
anirudh@anirudh-Aspire-5920:~/Desktop/testing$ 

问题1:当我在读取调用中输入地址2000时read(STDIN_FILENO,(int *)2000,3); 那么地址在哪里。我认为这是我试图访问的 RAM 的绝对地址。我是对的还是它偏移并添加到堆栈段基地址。我不知道。该程序没有为我提供内存违规的SEGFAULT,而是给我错误地址

问题2:好的,所以当我给出输入时代码崩溃了as lls 并且 bash 执行该“lls”的“ls”部分。原因是代码在读取第一个“l”后崩溃,其余“ls”部分由bash执行。但为什么 bash 执行左边的“ls”部分。为什么 bash 这样做是因为我的代码崩溃了,即使 bash 是它的父进程,它也不应该从我编写的代码打开的文件描述符(STDIN_FILNO)中读取。 (我想是的)...

感谢您的宝贵时间。

So this is the code I am trying to run:

#include<fcntl.h>
#include<stdio.h>
#include<errno.h>
#include<string.h>
#include<unistd.h>

int main(){

  int ret;

  ret = read(STDIN_FILENO,(int*)2000,3);
  printf("%d--%s\n",ret,strerror(errno));

  return 0;
}

and this is the output I get at the terminal

anirudh@anirudh-Aspire-5920:~/Desktop/testing$ gcc test.c 
anirudh@anirudh-Aspire-5920:~/Desktop/testing$ ./a.out 
lls
-1--Bad address
anirudh@anirudh-Aspire-5920:~/Desktop/testing$ ls
a.out  htmlget_ori.c  mysocket.cpp  Packet Sniffer.c  resolutionfinder.c  test.c
anirudh@anirudh-Aspire-5920:~/Desktop/testing$ 

Question 1: When I type the address 2000 in th read call read(STDIN_FILENO,(int*)2000,3);
then where does the address lies. I think this is the absolute address of the RAM that I am trying to access. am I right or is it offset and is added to the Stack Segment Base Address. I do not know. The program is not giving me a SEGFAULT for memory violation rather gives me Bad address

Question 2: Okay so the code crashes when I give the input as lls and bash executes the "ls" part of that "lls". The reason is that the code crashes after reading the first "l" and the rest "ls" part is executed by bash. but why bash is executing the left "ls" part. Why is bash doing so because my code is crashed and even if bash was its parent process it should not read from the file-descriptor (STDIN_FILNO) opened by the code I wrote. ( I think so)...

Thanks for your time.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

ˉ厌 2024-10-22 08:28:02

您尝试用作地址的 2000特定于进程虚拟地址。很可能没有任何内容映射到该范围;您可以添加此代码来查看当前的映射:

char cmd[20];

sprintf(cmd, "pmap -x %i", getpid());
printf("%s\n", cmd);
system(cmd);

如果您确实必须访问2000左右的系统 RAM(我无法想象您是这样),使用 iopl(2) 系统调用将该地址范围映射到进程内存空间。并注意后果。 :)

至于其余的 ls 行为,请尝试将 \n 添加到您的 printf() 格式字符串中,我发现不正确地刷新输出可能会导致看起来令人困惑的交互,也许这只是令人困惑,而不是完全奇怪。 :)

The 2000 that you are trying to use as an address is a process-specific virtual address. Chances are good that nothing is mapped into that range; you can add this code to see what your mappings currently are:

char cmd[20];

sprintf(cmd, "pmap -x %i", getpid());
printf("%s\n", cmd);
system(cmd);

If you really must gain access to system RAM around 2000 (and I can't imagine that you are), use the iopl(2) system call to map that address range into your process memory space. And beware the consequences. :)

As for the rest of the ls behaviour, try adding a \n to your printf() format string, I've found that not properly flushing output can lead to confusing-looking interaction, perhaps this is just confusing, rather than outright strange. :)

羁〃客ぐ 2024-10-22 08:28:02

您正在使用分页功能的 CPU 上运行。您的操作系统维护从虚拟地址转换为物理地址的页表。您的进程的页表不包含虚拟地址 2000 的任何内容,因此 read() 会注意到,并返回 -EFAULT

stdin 已连接到您的终端设备 (/dev/tty)。您的进程从 shell 继承该终端,并且 shell 在进程退出时将其取回。

You are running on a CPU with paging. Your OS maintains page tables which translate from virtual to physical addresses. The page table for your process doesn't contain anything for virtual address 2000, so read() notices, and returns -EFAULT.

stdin is connected to your terminal device (/dev/tty). Your process inherits that terminal from your shell, and the shell gets it back on process exit.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文