strerror突然想到的问题(Linux系统)
本帖最后由 我就是个弟弟 于 2019-6-19 19:47 编辑char *strerror (int __errnum);
这个函数返回的字符串,的生命周期。
字符串的地址在哪里?
这个,我是真不会。。。 如果是这个函数的话,我猜想他的字符串在程序的数据段的(静态)。
可以反汇编调试下找找哈哈
或者把你编译好的ELF格式文件载入IDA查找一下字符串验证下{:10_266:},思路就说到这了 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>: callq0x400740 <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>: callq0x4006e0 <__errno_location@plt>
0x0000000000400901 <+65>: mov (%rax),%edi
0x0000000000400903 <+67>: callq0x4006f0 <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>: callq0x400720 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt>
0x000000000040091f <+95>: movabs $0x400700,%rsi
0x0000000000400929 <+105>: mov %rax,%rdi
0x000000000040092c <+108>: callq0x400730 <_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.
看不懂。。。。 我就是个弟弟 发表于 2019-6-19 20:01
Dump of assembler code for function main(int, char const**):
12 {
0x00000000004008c0 : ...
把你编译好的程序传一下我试试 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
代码。 我就是个弟弟 发表于 2019-6-19 20:10
代码。
才菜了,没找到,用gdb跟下吧,懒的搞了{:10_266:} @人造人 大佬{:10_266:} newu 发表于 2019-6-19 20:39
才菜了,没找到,用gdb跟下吧,懒的搞了
{:10_266:}I am vegetable 就是一个static变量
static char buf;
/* 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));
/* 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;
return _strerror_internal (errnum, buf);
}
人造人 发表于 2019-6-19 21:37
就是一个static变量
哦, 大佬,是在动态链接库的内存里面是吗? 我就是个弟弟 发表于 2019-6-20 07:46
哦, 大佬,是在动态链接库的内存里面是吗?
这完全取决于实现,不同的实现位置很有可能不同
我查了一些源代码,发现strerror返回的这个字符串使用的是static局部变量,还有可能是常量字符串
不管是static局部变量,还是常量字符串,都在全局数据区
至于全局数据区是不是位于动态链接库,这要看实现
在linux下如果操作系统使用动态链接 .so文件,那全局数据区就在动态链接库中
如果使用静态链接库 .a文件,那strerror的这个字符串就和我们写的代码中的全局数据在同一个段,一般是同一个段,当然链接器完全可以弄到不同的段,strerror返回的字符串位置完全取决于实现
页:
[1]