简体   繁体   English

Linux(GCC)上的分段错误

[英]Segmentation fault on linux (gcc)

I am debugging a numerical program. 我正在调试数字程序。 It works well on Windows (Visual Studio compiler), giving the correct results. 它在Windows(Visual Studio编译器)上运行良好,给出了正确的结果。

Unfortunately on Linux (Ubuntu 12.04 x64) with gcc the program is giving segmentation fault after some part of computations (I am getting part of results). 不幸的是,在带有gcc的Linux(Ubuntu 12.04 x64)上,该程序在进行了部分计算后给出了分段错误(我得到了部分结果)。

I tried to use Valgrind to debug it, and to get a place where I may expect the error. 我尝试使用Valgrind对其进行调试,并找到一个可能发生此错误的地方。

The results are: 结果是:

==19565== Memcheck, a memory error detector
==19565== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==19565== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==19565== Command: ./a.out
==19565==
==19565== Invalid read of size 8
==19565==    at 0x402E50: MAXN(double, int, double, int*, double*,
int, double*, double*, double*, double*, int*, int*, double, double*,
int*, double) (in /home/muniek/Desktop/c_code/a.out)
==19565==    by 0x401991: main (in /home/muniek/Desktop/c_code/a.out)
==19565==  Address 0x54f0958 is not stack'd, malloc'd or (recently) free'd
==19565==
==19565== Invalid read of size 8
==19565==    at 0x402E65: MAXN(double, int, double, int*, double*,
int, double*, double*, double*, double*, int*, int*, double, double*,
int*, double) (in /home/muniek/Desktop/c_code/a.out)
==19565==    by 0x401991: main (in /home/muniek/Desktop/c_code/a.out)
==19565==  Address 0x54f0950 is not stack'd, malloc'd or (recently) free'd
==19565==
==19565== Invalid read of size 8
==19565==    at 0x402E85: MAXN(double, int, double, int*, double*,
int, double*, double*, double*, double*, int*, int*, double, double*,
int*, double) (in /home/muniek/Desktop/c_code/a.out)
==19565==    by 0x401991: main (in /home/muniek/Desktop/c_code/a.out)
==19565==  Address 0x54f0958 is not stack'd, malloc'd or (recently) free'd
==19565==
==19565== Invalid read of size 8
==19565==    at 0x402E9A: MAXN(double, int, double, int*, double*,
int, double*, double*, double*, double*, int*, int*, double, double*,
int*, double) (in /home/muniek/Desktop/c_code/a.out)
==19565==    by 0x401991: main (in /home/muniek/Desktop/c_code/a.out)
==19565==  Address 0x54f0960 is not stack'd, malloc'd or (recently) free'd
==19565==
==19565== Invalid read of size 8
==19565==    at 0x402D82: MAXN(double, int, double, int*, double*,
int, double*, double*, double*, double*, int*, int*, double, double*,
int*, double) (in /home/muniek/Desktop/c_code/a.out)
==19565==    by 0x401991: main (in /home/muniek/Desktop/c_code/a.out)
==19565==  Address 0x54f0978 is 8 bytes before a block of size 1,696 alloc'd
==19565==    at 0x4C29DB4: calloc (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==19565==    by 0x404CC0: dvector(int, int) (in
/home/muniek/Desktop/c_code/a.out)
==19565==    by 0x400A62: main (in /home/muniek/Desktop/c_code/a.out)
==19565==
==19565==
==19565== HEAP SUMMARY:
==19565==     in use at exit: 1,704 bytes in 3 blocks
==19565==   total heap usage: 1,228,705 allocs, 1,228,702 frees,
9,826,265,416 bytes allocated
==19565==
==19565== 568 bytes in 1 blocks are still reachable in loss record 1 of 3
==19565==    at 0x4C2B6CD: malloc (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==19565==    by 0x519D20A: __fopen_internal (iofopen.c:76)
==19565==    by 0x401100: main (in /home/muniek/Desktop/c_code/a.out)
==19565==
==19565== 568 bytes in 1 blocks are still reachable in loss record 2 of 3
==19565==    at 0x4C2B6CD: malloc (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==19565==    by 0x519D20A: __fopen_internal (iofopen.c:76)
==19565==    by 0x401116: main (in /home/muniek/Desktop/c_code/a.out)
==19565==
==19565== 568 bytes in 1 blocks are still reachable in loss record 3 of 3
==19565==    at 0x4C2B6CD: malloc (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==19565==    by 0x519D20A: __fopen_internal (iofopen.c:76)
==19565==    by 0x40112C: main (in /home/muniek/Desktop/c_code/a.out)
==19565==
==19565== LEAK SUMMARY:
==19565==    definitely lost: 0 bytes in 0 blocks
==19565==    indirectly lost: 0 bytes in 0 blocks
==19565==      possibly lost: 0 bytes in 0 blocks
==19565==    still reachable: 1,704 bytes in 3 blocks
==19565==         suppressed: 0 bytes in 0 blocks
==19565==
==19565== For counts of detected and suppressed errors, rerun with: -v
==19565== ERROR SUMMARY: 2664 errors from 5 contexts (suppressed: 2 from 2)

I got it that there is some problem in MAXN function (am I right?). 我知道MAXN函数存在一些问题(对吗?)。

void MAXN (double AMP, int ix, double DX, int *NST, double* ETE, int SP, double* C0, double* X0, double* CR, double* XC, int *N0, int *NC, double T,
  double *T0, int* GPC, double PER)
{
  double XCC, PFIX, TN;
  int SX0, ST, FN, N;

  ST = NINT((0.5/DX)+1);
  FN = NINT((1.0/DX)+1);

  PFIX = 3.0*PER/4.0;
  TN = T;
  SX0 = NINT((X0[*NST]/DX)+1);

  if (SX0 > SP+5)
    (*NST)++;

  //checks for new wave crests entering the computational domain
  for (int i = ST; i <= FN; i++)
  {
    if ((ETE[i] > ETE[i-1]) && (ETE[i] > ETE[i+1]) && (ETE[i] > 0) && (ETE[i] > (AMP/4.0)))
    {
      XCC = double((i-1)*DX);
      if ((XCC < (X0[*NC]-DX)) && ((TN-*T0) > PFIX))
      {
        *NC = *N0 + 1;
        XC[*NC] = XCC;
        CR[*NC] = ETE[i];
        *T0 =T;
         goto stop;
      }
    }
  }
  stop://label 2 continue

  //tracks existing wave crests within the computational domain
  for (int j = *NST; j <= *NC; j++)
  {
    N = NINT((X0[j]/DX)+1);
    int NCC = 0;

    for (int i = (N - 1); i <= (N + ST); i++)
    {
      if ((ETE[i] > ETE[i-1]) && (ETE[i] > ETE[i+1]) && (ETE[i] > 0))
      {
        NCC++;
        CR[j] = ETE[i];
        XC[j] = double((i-1)*DX);
      }

      if (NCC == 0)
      {
        for (int k = N-10; k <= N+10; k++)
        {
          if ((ETE[k] > ETE[k-1]) && (ETE[k] > ETE[k+1]) && (ETE[k] > 0))
          {
            CR[j] = ETE[k];
            XC[j] = double((k-1)*DX);
          }
        }
      }
    }
  }
  //update wave crests and position for next step
  for (int i = *NST; i <= *NC; i++)
  {
    GPC[i] = NINT((XC[i]/DX)+1);
    X0[i] = XC[i];
    C0[i] = CR[i];
  }

  *N0 = *NC;
}

How I can get more precisely the place of code which causes the segfault? 我如何更精确地找到导致段错误的代码位置? What part of code can do that? 代码的哪一部分可以做到这一点?

compile your code with debugging support and use GDB to run your code. 在调试支持下编译代码并使用GDB运行代码。 When the segfault happens you can look at the trace and see where the error occurred. 发生段故障时,您可以查看跟踪并查看错误发生的位置。

Are you compiling your program with debug information? 您是否在使用调试信息编译程序? This is enabled by running gcc with the -g option. 通过使用-g选项运行gcc可以启用此功能。 If your program has debug info, valgrind will tell the line number where the invalid access occured. 如果您的程序具有调试信息,则valgrind将告诉行号发生无效访问的位置。 And with debug info you'll also have a much easier time using gdb. 借助调试信息,您还将更轻松地使用gdb。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM