鱼C论坛

 找回密码
 立即注册
查看: 1953|回复: 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变量
static char buf[1024];
/* Copyright (C) 1991, 1993, 1994 Free Software Foundation, Inc.
This file is part of the GNU C Library.

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

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

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

#include <ansidecl.h>
#include <stdio.h>
#include <string.h>

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

/* Return a string descibing the errno code in ERRNUM.
   The storage is good only until the next call to strerror.
   Writing to the storage causes undefined behavior.  */
char *
DEFUN(strerror, (errnum), int errnum)
{
  static char buf[1024];
  return _strerror_internal (errnum, buf);
}
想知道小甲鱼最近在做啥?请访问 -> 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
把你编译好的程序传一下我试试
#include <iostream>
#include <dirent.h>
#include <sys/types.h>
#include <string.h>
#include <linux/errno.h>

using std::endl;
using std::cout;
using std::cerr;

int main(int, const char **)
{
    const char *path = "/tmp/pylearn_";
    DIR *dir = opendir(path);

    if (dir == nullptr) {
        const char *error_log = strerror(errno);
        cerr << error_log << endl;
    }

    return 0;
}

// 0x7ffff70eba40
// 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变量
static char buf[1024];
/* Copyright (C) 1991, 1993, 1994 Free Software Foundation, Inc.
This file is part of the GNU C Library.

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

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

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

#include <ansidecl.h>
#include <stdio.h>
#include <string.h>

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

/* Return a string descibing the errno code in ERRNUM.
   The storage is good only until the next call to strerror.
   Writing to the storage causes undefined behavior.  */
char *
DEFUN(strerror, (errnum), int errnum)
{
  static char buf[1024];
  return _strerror_internal (errnum, buf);
}
想知道小甲鱼最近在做啥?请访问 -> 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-10-3 21:23

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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