我正在调试一个数字程序。它在Windows(Visual Studio编译器)上运行良好,给出了正确的结果。
不幸的是在使用gcc的Linux(Ubuntu 12.04 x64)上,程序在计算一部分后会产生分段错误(我得到了部分结果)。
我尝试使用Valgrind来调试它,并找到一个可能出现错误的地方。
结果是:
==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)
我知道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;
}
如何更精确地获取导致段错误的代码位置?代码的哪一部分可以做到这一点?
答案 0 :(得分:3)
使用调试支持编译代码并使用GDB运行代码。发生段错误时,您可以查看跟踪并查看错误发生的位置。
答案 1 :(得分:0)
您是否正在使用调试信息编译程序?通过使用-g
选项运行gcc可以启用此功能。如果您的程序有调试信息,valgrind将告诉发生无效访问的行号。使用调试信息,您还可以更轻松地使用gdb。