Valgrind:使用段错误写入大小为8的无效

时间:2015-06-19 22:07:58

标签: c segmentation-fault valgrind

所以我正在研究相当长的c代码来进行一些数据分析。当我运行它时,会出现段错误。我无法看到任何明显的东西,所以我通过valgrind运行它,在那里我得到以下内容:

==7136== Memcheck, a memory error detector
==7136== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==7136== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
==7136== Command: ./exspec table.dat datafile_1
==7136== 
Reading in table...
Obtaining rates...
Loading data from file...
==7136== Warning: set address range perms: large range [0x3a00e040,     0xaa00e040) (defined)
==7136== Warning: set address range perms: large range [0xaa00f040, 0xdc11a5e0) (defined)
==7136== Warning: set address range perms: large range [0x3a00e028, 0xaa00e058) (noaccess)
Converting units...
Computing fractions...
Calculating LOS and particle intersections...
==7136== Warning: client switching stacks?  SP change: 0xffefffc60 -->    0xffb6c81a0
==7136==          to suppress, use: --max-stackframe=59996864 or greater
==7136== Invalid write of size 8
==7136==    at 0x4040DD: get_particle_intersections (los.c:105)
==7136==    by 0x403E77: los (los.c:65)
==7136==    by 0x401236: main (main.c:73)
==7136==  Address 0xffb6c8198 is on thread 1's stack
==7136== 
==7136== 
==7136== Process terminating with default action of signal 11 (SIGSEGV)
==7136==  Access not within mapped region at address 0xFFB6C8198
==7136==    at 0x4040DD: get_particle_intersections (los.c:105)
==7136==  If you believe this happened as a result of a stack
==7136==  overflow in your program's main thread (unlikely but
==7136==  possible), you can try to increase the size of the
==7136==  main thread stack using the --main-stacksize= flag.
==7136==  The main thread stack size used in this run was 8388608.
==7136== 
==7136== Process terminating with default action of signal 11 (SIGSEGV)
==7136==  Access not within mapped region at address 0xFFB6C8191
==7136==    at 0x4A256B0: _vgnU_freeres (in /usr/lib/valgrind/vgpreload_core-amd64-linux.so)
==7136==  If you believe this happened as a result of a stack
==7136==  overflow in your program's main thread (unlikely but
==7136==  possible), you can try to increase the size of the
==7136==  main thread stack using the --main-stacksize= flag.
==7136==  The main thread stack size used in this run was 8388608.
==7136== 
==7136== HEAP SUMMARY:
==7136==     in use at exit: 840,104,888 bytes in 4 blocks
==7136==   total heap usage: 1,447 allocs, 1,443 frees, 2,720,608,224 bytes allocated
==7136== 
==7136== LEAK SUMMARY:
==7136==    definitely lost: 0 bytes in 0 blocks
==7136==    indirectly lost: 0 bytes in 0 blocks
==7136==      possibly lost: 0 bytes in 0 blocks
==7136==    still reachable: 840,104,888 bytes in 4 blocks
==7136==         suppressed: 0 bytes in 0 blocks
==7136== Rerun with --leak-check=full to see details of leaked memory
==7136== 
==7136== For counts of detected and suppressed errors, rerun with: -v
==7136== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Segmentation fault (core dumped)

这里说的是无效写入的功能(无论如何,因为它有点长):

void get_particle_intersections(void)
{
   int i;
   int j;
   int tot_overlap = 0;
   int list[ngas];
   float x;
   float y;
   float z;
   float h;

       for(i = 0; i < NPIXELS; i++)
       {
          pixels[i].noverlap = 0;

          for(j = 0; j < ngas; j++)
          {
             x = (pixels[i].pos[0] - P[j].pos[0]) / CM_PER_KPC;
             y = (pixels[i].pos[1] - P[j].pos[1]) / CM_PER_KPC;
             z = (pixels[i].pos[2] - P[j].pos[2]) / CM_PER_KPC;
             h = P[j].hsml / CM_PER_KPC;

             if((pow(x, 2.0) + pow(y, 2.0) + pow(z, 2.0)) <= pow(h, 2.0))
             {
                 // Do stuff
             }
             // Do more stuff
         }
         // More stuff
     }

105行是if(pow ...行。像素和P都是全局变量,其内存分配在其他地方:

if(!(pixels = calloc(NPIXELS, sizeof(PIXEL))))
{
    printf("Error, couldn't allocate memory for pixels!\n");
    exit(EXIT_FAILURE);
}

if(!(P = calloc(n_gas, sizeof(DATA))))
{
    printf("Error, couldn't allocate memory for particles!\n");
    exit(EXIT_FAILURE);
}

它们被声明为:

PIXEL *pixels;
DATA *P;

像素和P内的pos数组声明为:

float pos[3];

PIXEL和DATA是typedef结构。我之所以问的原因是,如果seg错误是由于无效写入造成的,那么我就不会理解错误,因为该行没有写入任何内容。这让我相信实际错误是在这一行之前,但无论出于什么原因,它只是在第105行标记它。无论如何,就像我说的那样,代码相当长,所以我还没有发布所有的错误,我想这可能是错误发生在其他地方,但由于那个程序崩溃的地方,我只是觉得我会发布那个部分。此外,此崩溃发生在代码的中间,因此在程序中此时已分配但尚未释放的多个数组。

我已经查看了与此站点上的无效写入相关的其他几个问题,并且所有内容似乎都与将一种数据类型分配给另一种数据类型或某些此类事物有关。因为valgrind告诉我错误是在if语句,但我想我会问。谢谢,抱歉相当长的帖子!

编辑:这是gdb的输出:

GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later    <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./exspec...done.
(gdb) start table.dat datafile_1 
Temporary breakpoint 1 at 0x40111c: file src/main.c, line 33.
Starting program: ./exspec table.dat datafile_1

Temporary breakpoint 1, main (argc=3, argv=0x7fffffffde88) at   src/main.c:33
33     start = clock();
(gdb) b los.c:88
Breakpoint 2 at 0x403f02: file src/los.c, line 88.
(gdb) c
Continuing.
Reading in table...
Obtaining rates...
Loading data from file...
Converting units...
Computing fractions...
Calculating LOS and particle intersections...

Breakpoint 2, get_particle_intersections () at src/los.c:88
88     for(i = 0; i < NPIXELS; i++)
(gdb) n
90        pixels[i].noverlap = 0;
(gdb) 
92        for(j = 0; j < ngas; j++)
(gdb) 
99           x = (pixels[i].pos[0] - P[j].pos[0]) / CM_PER_KPC;
(gdb) 
100          y = (pixels[i].pos[1] - P[j].pos[1]) / CM_PER_KPC;
(gdb) 
101          z = (pixels[i].pos[2] - P[j].pos[2]) / CM_PER_KPC;
(gdb) 
102          h = P[j].hsml / CM_PER_KPC;
(gdb) 
105          if((pow(x, 2.0) + pow(y, 2.0) + pow(z, 2.0)) <= pow(h, 2.0))
(gdb) 

Program received signal SIGSEGV, Segmentation fault.
0x00000000004040dd in get_particle_intersections () at src/los.c:105
105          if((pow(x, 2.0) + pow(y, 2.0) + pow(z, 2.0)) <= pow(h, 2.0))

0 个答案:

没有答案