首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Calloc正在返回一个导致我的程序分段错误的地址。

Calloc正在返回一个导致我的程序分段错误的地址。
EN

Stack Overflow用户
提问于 2014-12-02 23:35:15
回答 1查看 306关注 0票数 0

所以,首先,这是我所见过的最奇怪的错误。我不知道怎么回事。任何人能在正在发生的事情上提供任何帮助,都将不胜感激。

我正在编写一个C程序,它将文件读入动态分配的块中,并对这些块执行各种操作(加密/解密/MACing等)。当我在一定的(更大的?)上运行它时?文件是分段错误。我想我一定是在内存上,在哪里或者没有正确分配它。所以我在“勇敢”中运行它,试图找出发生了什么事情,问题就消失了。瓦伦报告没有错误,该程序没有分段错误,并按预期工作。

代码语言:javascript
复制
normal run
./threefizer -e -p 1234567 new_name.docx
...
[1]    25017 segmentation fault  ./threefizer -e -p 1234567 new_name.docx

valgrind run
valgrind ./threefizer -e -p 1234567 new_name.docx
==25238== Memcheck, a memory error detector
==25238== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==25238== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==25238== Command: ./threefizer -e -p 1234567 new_name.docx
==25238== 
...
Threefizer operation complete
==25238== 
==25238== HEAP SUMMARY:
==25238==     in use at exit: 0 bytes in 0 blocks
==25238==   total heap usage: 25 allocs, 25 frees, 977,995 bytes allocated
==25238== 
==25238== All heap blocks were freed -- no leaks are possible
==25238== 
==25238== For counts of detected and suppressed errors, rerun with: -v
==25238== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)

这是怎么回事?我以前见过val研防止分段错误,仅仅是因为它在自己的vm中分配内存的方式不同。但是,总是当我有这种情况发生之前,瓦兰报告,至少一个错误,某种类型。

深入挖掘gdb,我发现当我的程序试图修改从读取的文件中填充的块的内容时,总是会发生分段错误。

我的文件读取功能看起来像这样有人在这里看到什么问题了吗?从功能上看似乎很好。

代码语言:javascript
复制
uint8_t* readBlock(const uint64_t data_size, const FILE* read)
{
    pdebug("readBlock()\n");
    if(ferror(read))
    {
        fclose(read);
        perror("Error reading block\n");
        return NULL;
    }

    const uint8_t* data = calloc(data_size, sizeof(uint8_t));
    const uint64_t size = fread(data, sizeof(uint8_t), data_size, read);

    if(ferror(read))
    {
        fclose(read);
        perror("Error reading block\n");
        return NULL;
    }

    if(size == data_size)
    {
        return data;
    }

    perror("Unable to read requested number of bytes\n");
    free(data);
    return NULL;
}

gdb会话显示导致我的程序分段错误的读取。

代码语言:javascript
复制
***Before read***
queueFile()
Breakpoint 1, queueFile (args=0x7fffffffe460, out=0x62c030)
at controller.c:172
//this is where the data is being read and allocated
172                       data_chunk->data = pad(readBlock(orig_file_size, read),
(gdb) print data_chunk->data
$1 = (uint64_t *) 0x0 //the brand new pointer is null as it should be with nothing allocated

***After read***
(gdb) next
readBlock()
176                       data_chunk->data_size = getPadSize(orig_file_size, args>state_size);
(gdb) print data_chunk->data
$4 = (uint64_t *) 0xfffffffff7ee7010 //why is this memory address so big?
(gdb) print data_chunk->data[0]
Cannot access memory at address 0xfffffffff7ee7010 //can't access memory WTF?
//When this pointer is getting passed to anything else that attempts to access or modify it then the program segfaults

当程序试图对来自readBlock()的数据执行任何操作时,它都会发生分段错误。在这种情况下,它试图加密它。

代码语言:javascript
复制
***Interestingly the address that is causing the program to segfault is 12 hex digits instead of the regular 6 why?***
Program received signal SIGSEGV, Segmentation fault.
0x0000000000402413 in cbc512Encrypt (key=0x62be78 <runThreefizer.tf_key>, 
iv=0x62c2b0, plain_text=0xfffffffff7ee7010, num_blocks=7611) at cbc.c:206
206     plain_text[0] ^= iv[0]; plain_text[1] ^= iv[1]; plain_text[2] ^= iv[2]; plain_text[3] ^= iv[3];

使用gdb时,当我试图访问readBlock()中的相同内存时,我可以很好地访问它,并且它包含它正在读取的文件的适当内容。

代码语言:javascript
复制
***GDB session showing the readBlock() that runs before segfault***
(gdb) continue
Continuing.
readBlock()

Breakpoint 2, readBlock (data_size=487073, read=0x62c360) at fileIO.c:40
40          return data;
(gdb) print data
$7 = (uint8_t *) 0x7ffff7f5e010 "PK\003\004\024" //again whats with the giant memory address all the other ones are only 6 hex digits
(gdb) print size
$8 = 487073
(gdb) print data[0] //as you can see we can access the data just fine and its contents correspond to the first 8 characters of the file that was read
$9 = 80 'P'
(gdb) print data[1]
$10 = 75 'K'
(gdb) print data[2]
$11 = 3 '\003'
(gdb) print data[3]
$12 = 4 '\004'
(gdb) print data[4]
$13 = 20 '\024'
(gdb) print data[5]
$14 = 0 '\000'
(gdb) print data[6]
$15 = 6 '\006'
(gdb) print data[7]
$16 = 0 '\000'
(gdb) 

***The same memory address is inaccessible from the function that calls readBlock()***
(gdb) break controller.c:173
Breakpoint 3 at 0x4038fa: file controller.c, line 173.
(gdb) continue
Continuing.

Breakpoint 3, queueFile (args=0x7fffffffe460, out=0x62c030)
at controller.c:176
176                       data_chunk->data_size = getPadSize(orig_file_size, args->state_size);
(gdb) print data_chunk->data
$17 = (uint64_t *) 0xfffffffff7ee7010 //this is the same address as data in readBlock() and also returned by readBlock()
(gdb) print data_chunk->data[0] 
Cannot access memory at address 0xfffffffff7ee7010 //WHY NOT!?

所以你有了,有人知道怎么回事吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-12-03 10:09:47

我能猜一下吗?您在哪里调用了readBlock(),您是否确保包含了readBlock的原型?我问的原因是,在readBlock内部,您的data似乎有一个0x7ffff7f5e010的地址,但是在调用者中,它似乎已经更改为类似0xfffffffff7ee7010的东西。如果调用方认为readBlock正在返回int (即没有原型),则可能发生这种情况。

我抄袭了我的评论,因为它解决了你的问题。顺便说一句,+1是少数使用调试器并试图隔离问题的人之一。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27261032

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档