鱼C论坛

 找回密码
 立即注册
查看: 1553|回复: 10

[已解决]strerror突然想到的问题(Linux系统)

[复制链接]
发表于 2019-6-19 19:45:41 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 我就是个弟弟 于 2019-6-19 19:47 编辑

char *strerror (int __errnum);

这个函数返回的字符串,的生命周期。
字符串的地址在哪里?

这个,我是真不会。。。
最佳答案
2019-6-19 21:37:28
就是一个static变量
  1. static char buf[1024];
复制代码

  1. /* Copyright (C) 1991, 1993, 1994 Free Software Foundation, Inc.
  2. This file is part of the GNU C Library.

  3. The GNU C Library is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU Library General Public License as
  5. published by the Free Software Foundation; either version 2 of the
  6. License, or (at your option) any later version.

  7. The GNU C Library is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  10. Library General Public License for more details.

  11. You should have received a copy of the GNU Library General Public
  12. License along with the GNU C Library; see the file COPYING.LIB.  If
  13. not, write to the Free Software Foundation, Inc., 675 Mass Ave,
  14. Cambridge, MA 02139, USA.  */

  15. #include <ansidecl.h>
  16. #include <stdio.h>
  17. #include <string.h>

  18. extern char *_strerror_internal __P ((int, char buf[1024]));

  19. /* Return a string descibing the errno code in ERRNUM.
  20.    The storage is good only until the next call to strerror.
  21.    Writing to the storage causes undefined behavior.  */
  22. char *
  23. DEFUN(strerror, (errnum), int errnum)
  24. {
  25.   static char buf[1024];
  26.   return _strerror_internal (errnum, buf);
  27. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-6-19 19:52:11 | 显示全部楼层
如果是这个函数的话,我猜想他的字符串在程序的数据段的(静态)。

可以反汇编调试下找找哈哈

或者把你编译好的ELF格式文件载入IDA查找一下字符串验证下,思路就说到这了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-6-19 20:01:29 | 显示全部楼层
newu 发表于 2019-6-19 19:52
如果是这个函数的话,我猜想他的字符串在程序的数据段的(静态)。

可以反汇编调试下找找哈哈

Dump of assembler code for function main(int, char const**):
12      {
   0x00000000004008c0 <+0>:     push   %rbp
   0x00000000004008c1 <+1>:     mov    %rsp,%rbp
   0x00000000004008c4 <+4>:     sub    $0x30,%rsp
   0x00000000004008c8 <+8>:     movabs $0x4009c4,%rax
   0x00000000004008d2 <+18>:    movl   $0x0,-0x4(%rbp)
   0x00000000004008d9 <+25>:    mov    %edi,-0x8(%rbp)
   0x00000000004008dc <+28>:    mov    %rsi,-0x10(%rbp)

13          const char *path = "/tmp/pylearn_";
   0x00000000004008e0 <+32>:    mov    %rax,-0x18(%rbp)

14          DIR *dir = opendir(path);
   0x00000000004008e4 <+36>:    mov    -0x18(%rbp),%rdi
   0x00000000004008e8 <+40>:    callq  0x400740 <opendir@plt>
   0x00000000004008ed <+45>:    mov    %rax,-0x20(%rbp)

15
16          if (dir == nullptr) {
   0x00000000004008f1 <+49>:    cmpq   $0x0,-0x20(%rbp)
   0x00000000004008f6 <+54>:    jne    0x400935 <main(int, char const**)+117>

17              const char *error_log = strerror(errno);
   0x00000000004008fc <+60>:    callq  0x4006e0 <__errno_location@plt>
   0x0000000000400901 <+65>:    mov    (%rax),%edi
   0x0000000000400903 <+67>:    callq  0x4006f0 <strerror@plt>
   0x0000000000400908 <+72>:    movabs $0x601080,%rdi
   0x0000000000400912 <+82>:    mov    %rax,-0x28(%rbp)

18              cerr << error_log << endl;
   0x0000000000400916 <+86>:    mov    -0x28(%rbp),%rsi
   0x000000000040091a <+90>:    callq  0x400720 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt>
   0x000000000040091f <+95>:    movabs $0x400700,%rsi
   0x0000000000400929 <+105>:   mov    %rax,%rdi
   0x000000000040092c <+108>:   callq  0x400730 <_ZNSolsEPFRSoS_E@plt>
   0x0000000000400931 <+113>:   mov    %rax,-0x30(%rbp)
--Type <RET> for more, q to quit, c to continue without paging--
   0x0000000000400935 <+117>:   xor    %eax,%eax

19          }
20
21          return 0;
   0x0000000000400937 <+119>:   add    $0x30,%rsp
   0x000000000040093b <+123>:   pop    %rbp
   0x000000000040093c <+124>:   retq   

End of assembler dump.



看不懂。。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-6-19 20:09:33 | 显示全部楼层
我就是个弟弟 发表于 2019-6-19 20:01
Dump of assembler code for function main(int, char const**):
12      {
   0x00000000004008c0 :   ...

把你编译好的程序传一下我试试
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-6-19 20:10:56 | 显示全部楼层
newu 发表于 2019-6-19 20:09
把你编译好的程序传一下我试试
  1. #include <iostream>
  2. #include <dirent.h>
  3. #include <sys/types.h>
  4. #include <string.h>
  5. #include <linux/errno.h>

  6. using std::endl;
  7. using std::cout;
  8. using std::cerr;

  9. int main(int, const char **)
  10. {
  11.     const char *path = "/tmp/pylearn_";
  12.     DIR *dir = opendir(path);

  13.     if (dir == nullptr) {
  14.         const char *error_log = strerror(errno);
  15.         cerr << error_log << endl;
  16.     }

  17.     return 0;
  18. }

  19. // 0x7ffff70eba40
  20. // 0x7ffff72020f2
复制代码


代码。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-6-19 20:39:22 | 显示全部楼层

才菜了,没找到,用gdb跟下吧,懒的搞了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-6-19 20:51:17 | 显示全部楼层
@人造人 大佬
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-6-19 20:52:03 | 显示全部楼层
newu 发表于 2019-6-19 20:39
才菜了,没找到,用gdb跟下吧,懒的搞了

I am vegetable
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-6-19 21:37:28 | 显示全部楼层    本楼为最佳答案   
就是一个static变量
  1. static char buf[1024];
复制代码

  1. /* Copyright (C) 1991, 1993, 1994 Free Software Foundation, Inc.
  2. This file is part of the GNU C Library.

  3. The GNU C Library is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU Library General Public License as
  5. published by the Free Software Foundation; either version 2 of the
  6. License, or (at your option) any later version.

  7. The GNU C Library is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  10. Library General Public License for more details.

  11. You should have received a copy of the GNU Library General Public
  12. License along with the GNU C Library; see the file COPYING.LIB.  If
  13. not, write to the Free Software Foundation, Inc., 675 Mass Ave,
  14. Cambridge, MA 02139, USA.  */

  15. #include <ansidecl.h>
  16. #include <stdio.h>
  17. #include <string.h>

  18. extern char *_strerror_internal __P ((int, char buf[1024]));

  19. /* Return a string descibing the errno code in ERRNUM.
  20.    The storage is good only until the next call to strerror.
  21.    Writing to the storage causes undefined behavior.  */
  22. char *
  23. DEFUN(strerror, (errnum), int errnum)
  24. {
  25.   static char buf[1024];
  26.   return _strerror_internal (errnum, buf);
  27. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-6-20 07:46:52 | 显示全部楼层
人造人 发表于 2019-6-19 21:37
就是一个static变量

哦, 大佬,是在动态链接库的内存里面是吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-6-20 14:13:13 | 显示全部楼层
我就是个弟弟 发表于 2019-6-20 07:46
哦, 大佬,是在动态链接库的内存里面是吗?

这完全取决于实现,不同的实现位置很有可能不同

我查了一些源代码,发现strerror返回的这个字符串使用的是static局部变量,还有可能是常量字符串
不管是static局部变量,还是常量字符串,都在全局数据区
至于全局数据区是不是位于动态链接库,这要看实现
在linux下如果操作系统使用动态链接 .so文件,那全局数据区就在动态链接库中
如果使用静态链接库 .a文件,那strerror的这个字符串就和我们写的代码中的全局数据在同一个段,一般是同一个段,当然链接器完全可以弄到不同的段,strerror返回的字符串位置完全取决于实现
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-19 21:52

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表