+ -
当前位置:首页 → 问答吧 → 大师请进,在linux上,好像无法对栈上的内容进行修改?

大师请进,在linux上,好像无法对栈上的内容进行修改?

时间:2010-06-27

来源:互联网

我刚写一个lowercase的函数,但发现当输入是“char* dest = " HELlo WosLD ";”时执行到“string += 32;”,linux会抛那个段错误,而当输入已经malloc了,是不会出现这个段错误的,请问各位大师,有什么办法避免这个段错误?
  1. char* lowercase(char string[]){
  2.         int i=0;
  3.         char* res = string;
  4.         for(i=0;string[i];i++){
  5.                 string[i] += 32;
  6.         }
  7.         return (res);
  8. }

  9. int main(void){
  10.         char* dest = " HELlo WosLD ";
  11.         dest = lowercase(dest);
  12.         printf("the string after lowercase:%s\n",dest);

  13. }
复制代码

作者: ikewu83   发布时间: 2010-06-27

那是rodata

作者: prolj   发布时间: 2010-06-27



QUOTE:
那是rodata
prolj 发表于 2010-06-27 14:25




    嗯,而且不是栈上数据。

作者: 变异老鼠   发布时间: 2010-06-27

本帖最后由 ikewu83 于 2010-06-27 14:51 编辑

先谢谢了,那么一般在写类似Lowercase函数的时候,假设它的输入不是rodata吗?有什么更变通的方法?

作者: ikewu83   发布时间: 2010-06-27

char dest[] = " HELlo WosLD ";

作者: prolj   发布时间: 2010-06-27

回复 prolj


    这个好像会跑错。我的问题是我们一定要假设类似lowercase函数的输入不是rodata吗?有什么更变通的方法?

作者: ikewu83   发布时间: 2010-06-27

汇编
  1. .file        "hack1.c"
  2.         .text
  3. .globl lowercase
  4.         .type        lowercase, @function
  5. lowercase:
  6.         pushl        %ebp
  7.         movl        %esp, %ebp
  8.         subl        $16, %esp
  9.         movl        $0, -4(%ebp)
  10.         movl        8(%ebp), %eax
  11.         movl        %eax, -8(%ebp)
  12.         movl        $0, -4(%ebp)
  13.         jmp        .L2
  14. .L3:
  15.         movl        -4(%ebp), %eax
  16.         addl        8(%ebp), %eax
  17.         movl        -4(%ebp), %edx
  18.         addl        8(%ebp), %edx
  19.         movzbl        (%edx), %edx
  20.         addl        $32, %edx
  21.         movb        %dl, (%eax)
  22.         addl        $1, -4(%ebp)
  23. .L2:
  24.         movl        -4(%ebp), %eax
  25.         addl        8(%ebp), %eax
  26.         movzbl        (%eax), %eax
  27.         testb        %al, %al
  28.         jne        .L3
  29.         movl        -8(%ebp), %eax
  30.         leave
  31.         ret
  32.         .size        lowercase, .-lowercase
  33.         .section        .rodata
  34. .LC0:
  35.         .string        " HELlo WosLD "
  36.         .align 4
  37. .LC1:
  38.         .string        "the string after lowercase:%s\n"
  39.         .text
  40. .globl main
  41.         .type        main, @function
  42. main:
  43.         pushl        %ebp
  44.         movl        %esp, %ebp
  45.         andl        $-16, %esp
  46.         subl        $32, %esp
  47.         movl        $.LC0, 28(%esp)
  48.         movl        28(%esp), %eax
  49.         movl        %eax, (%esp)
  50.         call        lowercase
  51.         movl        %eax, 28(%esp)
  52.         movl        $.LC1, %eax
  53.         movl        28(%esp), %edx
  54.         movl        %edx, 4(%esp)
  55.         movl        %eax, (%esp)
  56.         call        printf
  57.         leave
  58.         ret
  59.         .size        main, .-main
  60.         .ident        "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3"
  61.         .section        .note.GNU-stack,"",@progbits
复制代码
你自己看吧
.L0就是你的字符串的地址
在只读段
我懒得看了,你自己看吧

作者: ah13k   发布时间: 2010-06-27

C已经不能满足我了,我要玩儿C++。

作者: prolj   发布时间: 2010-06-27

回复 prolj

阴雨阿,阴雨阿!

作者: peidright   发布时间: 2010-06-27

Lz的c语言的写法就是不规范的

作者: ling0088   发布时间: 2010-06-27

本帖最后由 ikewu83 于 2010-06-27 20:25 编辑

回复 ling0088


    大师,我就是想知道在写类似Lowercase函数的时候,假设它的输入不是rodata吗?有什么更变通的方法?也就是怎么写的规范点?

作者: ikewu83   发布时间: 2010-06-27



QUOTE:
回复  ling0088


    大师,我就是想知道在写类似Lowercase函数的时候,假设它的输入不是rodata吗?有 ...
ikewu83 发表于 2010-06-27 20:22


先搞清概念。嗯。

作者: donglongchao   发布时间: 2010-06-27

不要做这样的假设,你必须知道

作者: Magic_LP   发布时间: 2010-06-27

回复 ikewu83


      char* dest = " HELlo WosLD ";
      dest指向的是字符串是只读的

      string += 32;
      你修改只读的字符串所以出错了

      改成 char dest[] = " HELlo WosLD "; 试试

作者: kmindg   发布时间: 2010-06-27

dest 这个指针在栈上,但指针指向的字符内容在只读段rodata里面,修改只读内容会导致异常(段错误)。

作者: 没本   发布时间: 2010-06-28