免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2035 | 回复: 7
打印 上一主题 下一主题

关于那个errno,我不发表任何意见,贴一点东西 [复制链接]

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2005-11-22 13:00 |只看该作者 |倒序浏览
[root@Flower root]# more 8.c
#include <stdio.h>
#include <errno.h>
main()
{
        printf("%d",errno);
}
[root@Flower root]# gcc -S 8.c
[root@Flower root]# more 8.s
        .file   "8.c"
        .section        .rodata
.LC0:
        .string "%d"
        .text
.globl main
        .type   main, @function
main:
        pushl   %ebp
        movl    %esp, %ebp
        subl    $8, %esp
        andl    $-16, %esp
        movl    $0, %eax
        addl    $15, %eax
        addl    $15, %eax
        shrl    $4, %eax
        sall    $4, %eax
        subl    %eax, %esp
        call    __errno_location
        movl    (%eax), %eax
        movl    %eax, 4(%esp)
        movl    $.LC0, (%esp)
        call    printf
        leave
        ret
        .size   main, .-main
        .ident  "GCC: (GNU) 4.0.2"
        .section        .note.GNU-stack,"",@progbits

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
2 [报告]
发表于 2005-11-22 13:27 |只看该作者
嗯。支持把学问继续做下去。
最好能查到 __errno_location 是什么,那才叫好呢。

论坛徽章:
0
3 [报告]
发表于 2005-11-22 15:23 |只看该作者
手头上的是glibc2.1.1,在其中的sysdeps/mach/start.c这个文件中定义了errno

  1. #ifndef _HURD_THREADVAR_H
  2. volatile int errno;
  3. #endif
复制代码

然后在sysdeps/unix/sysv/linux/bits/errno.h中有一下声明和macro


  1. # ifndef __ASSEMBLER__
  2. /* We now need a declaration of the `errno' variable.  */
  3. extern int errno;

  4. /* Function to get address of global `errno' variable.  */
  5. extern int *__errno_location __P ((void)) __attribute__ ((__const__));

  6. #  if defined _LIBC
  7. /* We wouldn't need a special macro anymore but it is history.  */
  8. #   define __set_errno(val) (*__errno_location ()) = (val)
  9. #  endif /* _LIBC */

  10. #  if !defined _LIBC || defined _LIBC_REENTRANT
  11. /* When using threads, errno is a per-thread value.  */
  12. #   define errno (*__errno_location ())
  13. #  endif
  14. # endif /* !__ASSEMBLER__ */

复制代码


sysdeps/generic/errno-loc.c这个文件中定义了__errno_location()

  1. #include <errno.h>
  2. #undef errno

  3. int *
  4. weak_const_function
  5. __errno_location (void)
  6. {
  7.    return &errno;
  8. }
复制代码



在glibc-doc这个文档中有以下描述
More importantly, <errno.h> redefines errno when _REENTRANT is defined, so that errno refers to the thread-specific errno location rather than the global errno variable. This is achieved by the following #define in <errno.h>:

        #define errno (*(__errno_location()))

which causes each reference to errno to call the __errno_location() function for obtaining the location where error codes are stored. libc provides a default definition of __errno_location() that always returns &errno (the address of the global errno variable). Thus, for programs not linked with LinuxThreads, defining _REENTRANT makes no difference w.r.t. errno processing. But LinuxThreads redefines __errno_location() to return a location in the thread descriptor reserved for holding the current value of errno for the calling thread. Thus, each thread operates on a different errno location.


thread的实现没去看,但是觉得基本上可以说明问题了

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
4 [报告]
发表于 2005-11-22 15:31 |只看该作者
呵呵。我还正在 svn gcc 的代码呢。
你倒已经找到了。
我一会儿同步完了之后,再看看 4.x 是怎么弄的。

非常感谢!
基本上能说明问题了。

论坛徽章:
0
5 [报告]
发表于 2005-11-22 15:35 |只看该作者
UP

But LinuxThreads redefines __errno_location() to return a location in the thread descriptor reserved for holding the current value of errno for the calling thread.

知识不够/
l显然ocation是进程的某个位置吗 但是进程却不能更改吗?比如在某个只读的地方。
thread descriptor 是PCB吗? 别笑话我哦~

论坛徽章:
0
6 [报告]
发表于 2005-11-22 16:49 |只看该作者
AIX版的:

#ifndef _KERNEL

#if defined(_THREAD_SAFE) || defined(_THREAD_SAFE_ERRNO)
/*
* Per thread errno is provided by the threads provider. Both the extern int
* and the per thread value must be maintained by the threads library.
*/
extern  int     *_Errno( void );
#define errno   (*_Errno())

#else

extern int errno;

#endif  /* _THREAD_SAFE || _THREAD_SAFE_ERRNO */

#endif  /* _KERNEL */

论坛徽章:
0
7 [报告]
发表于 2005-11-22 20:01 |只看该作者
应该是这个文件了,sysdeps/generic/errno.c,以下该文件的注释
/* Definition of `errno' variable.  Canonical version.
..........
建议该贴置为精华

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
8 [报告]
发表于 2005-11-22 20:13 |只看该作者
原帖由 er 于 2005-11-22 20:01 发表
应该是这个文件了,sysdeps/generic/errno.c,以下该文件的注释
/* Definition of `errno' variable.  Canonical version.
..........
建议该贴置为精华

呵呵,算不上是精华。
问题本来就是很垃圾的一个问题。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP