[c] bij definieren 1 extra variabele -> segmentation fault!?

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • roedi06
  • Registratie: Mei 2006
  • Laatst online: 15-09 21:49
Beste tweakers,

Op mijn werk, werk ik met SuSe Linux, thuis gebruik ik Ubuntu. Als ik op mijn werk een in C geschreven programma compileer met 'cc' of 'gcc' gaat dat prima. Bij mij thuis in Ubuntu krijg ik echter 'segmentation faults' bij het compileren van hetzelfde programma wat dus via SuSe wel goed compileert.

Het probleem is dus:
SuSe compileren - runnen in Ubuntu : OK
Ubuntu compileren - runnen in Ubuntu: Werkt niet.

Nu ben ik uiteraard gaan zoeken en zoeken wat het probleem zou kunnen zijn, maar 'segmentation fault' is een van de meest onduidelijke meldingen met veel mogelijke oorzaken. Waar ik nu achter ben gekomen na veel testen, is dat ik schijnbaar op een limiet zit, maar hoe ik het op moet lossen weet ik niet;
Ik heb het programma terug gebracht tot minder regels door te 'commenten' en ben steeds verder gaan werken door regels te 'uncommenten' om zodoende de fout te achterhalen, nu blijkt dat ik bij het deffinieeren van 1 variabele extra op een gegeven moment de segmentation faults krijg na compileren. Of het nu een 'float', 'int' of 'string' is, dat doet er niet toe heb ik getest. Compileren doet ie dus wel (zonder foutmelding), maar als ik m run, houdt ie er na de definitie van die bewuste variabele mee op met de melding: 'segmentation fault'.

Ik loop dus tegen een limiet aan, maar aan mijn pc kan het niet liggen, omdat die alle specificaties van mijn werk-pc op alle vlakken overtreft. Ik draai Ubuntu(64bit) in een VMware omgeving in Win7 (64bit), en omdat ik dacht dat ik tegen een memory-limiet aanliep heb ik Ubuntu meer memory gegeven via VMware, maar ook dat werkt niet..

Hebben jullie een idee dat ik over hoofd zie??

PS. Ik compileer als volgt: 'cc <programma.c> -o <programma.x> -lm

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 21:24

.oisyn

Moderator Devschuur®

Demotivational Speaker

Die segfault komt waarschijnlijk gewoon door memory trashing. Iets dat buiten de buffers schrijft, of schrijft naar geheugen dat al is vrijgegeven, of geheugen dat meerdere keren wordt vrijgegeven. Dat hij ergens anders crasht is slechts een symptoom, daar ligt de oorzaak niet.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • roedi06
  • Registratie: Mei 2006
  • Laatst online: 15-09 21:49
.oisyn schreef op vrijdag 26 maart 2010 @ 17:16:
Die segfault komt waarschijnlijk gewoon door memory trashing. Iets dat buiten de buffers schrijft, of schrijft naar geheugen dat al is vrijgegeven, of geheugen dat meerdere keren wordt vrijgegeven. Dat hij ergens anders crasht is slechts een symptoom, daar ligt de oorzaak niet.
Is er een manier om dat te testen?? Zou er een verklaarbare reden zijn waarom het op mijn werk wel werkt?

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 21:24

.oisyn

Moderator Devschuur®

Demotivational Speaker

Onder linux heb je geloof ik een tooltje genaamd valgrind, die controleert dat soort dingen.
Zou er een verklaarbare reden zijn waarom het op mijn werk wel werkt?
Het feit dat het niet crasht wil niet zeggen dat de code goed is. Het gaat gewoon toevallig goed.

Ongeïnitialiseerde pointers zijn trouwens ook een mooie kandidaat.

[ Voor 11% gewijzigd door .oisyn op 26-03-2010 17:34 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • VyperX
  • Registratie: Juni 2001
  • Laatst online: 14-08 13:04
Een andere optie die je kan doen is om te compilen met debug informatie (bij je compiler-flags '-g' toevoegen), en dan het programma draaien vanuit de debugger 'gdb'. Het is alleen wel zo dat bij debug builds alles sowieso met 0 wordt geinitialiseerd, ipv unspecified stuff.

My Dwarf Fortress ASCII Reward: ~~@~~####,.".D",.B""


Acties:
  • 0 Henk 'm!

  • roedi06
  • Registratie: Mei 2006
  • Laatst online: 15-09 21:49
VyperX schreef op vrijdag 26 maart 2010 @ 17:39:
Een andere optie die je kan doen is om te compilen met debug informatie (bij je compiler-flags '-g' toevoegen), en dan het programma draaien vanuit de debugger 'gdb'. Het is alleen wel zo dat bij debug builds alles sowieso met 0 wordt geinitialiseerd, ipv unspecified stuff.
Wat ik dan niet begrijp is dat een in SuSe gecompileerd zelfde programma, WEL perfect werkt in Ubuntu. Als ik precies hetzelfde bronbestand in Ubuntu compileer werkt het niet meer.. dat is toch raar?? kan het ook aan de compiler liggen??

Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 00:02
roedi06 schreef op vrijdag 26 maart 2010 @ 17:20:
Zou er een verklaarbare reden zijn waarom het op mijn werk wel werkt?
Andere compilerversie, andere compilerconfiguratie, andere libc, andere architectuur, toevallig andere heapadressering. Het kan van alles zijn. :) Ubuntu tweakt de compilerconfiguratie altijd ten behoeve van security (zo staat GCC's stack protector standaard aan, om maar wat te noemen). Daar krijg je andere code van.

Ik zou je aanraden je eens te verdiepen in hoe je programma's kunt debuggen onder Linux. Compileren met -g en vervolgens onder gdb starten bijvoorbeeld; simpelweg een backtrace produceren (met bt) doet al wonderen, en je kunt dan ook de waarden van variabelen bij de crash vinden. Dat is aanzienlijk makkelijker dan je met printf's behelpen.

Behalve je programma in de debugger te starten, kun je ook core-dumps in de debugger laden. Daarvoor moet je wel de resource limit voor core files hoog genoeg hebben staan; onder sommige distro's is die standaard nul. Als je bash gebruikt kun je 'm met ulimit -c unlimited op onbeperkt zetten, en dan krijg je bij een crash hopelijk segmentation fault (core dumped) te zien. Er wordt dan een core-file gedumpt in de huidige directory die je vervolgens weer kunt openen met gdb. Het voordeel daarvan is dat je je applicatie niet steeds in de debugger hoeft te starten.
VyperX schreef op vrijdag 26 maart 2010 @ 17:39:
Het is alleen wel zo dat bij debug builds alles sowieso met 0 wordt geinitialiseerd, ipv unspecified stuff.
Dat is onzin. GCC voegt met -g alleen (extra) debug-informatie toe. De gegenereerde uitvoerbare code verandert niet. Daarom kun je -g ook prima combineren met optimalisatie-flags, of debug-informatie uit een binary strippen voor een release.
.oisyn schreef op vrijdag 26 maart 2010 @ 17:33:
Onder linux heb je geloof ik een tooltje genaamd valgrind, die controleert dat soort dingen.
Valgrind is zeker een handige tool, vooral omdat het werkt op alle binaries zonder verdere instrumentatie, maar niet onder elke distro eenvoudig te installeren en omdat het als een processor-emulator werkt, kan het niet alle soorten fouten herkennen (in dit geval vooral het gebruik van ongeïntialiseerde data).

Om bufferoverflows en dergelijke te vinden kun je wel mudflap gebruiken, wat standaard onderdeel is van recente GCC distributies. Simpelweg compileren met -fmudflap en linken met -lmudflap. (mudflap verandert de gegenereerde code echter wél!)

[ Voor 5% gewijzigd door Soultaker op 26-03-2010 18:05 ]


Acties:
  • 0 Henk 'm!

  • roedi06
  • Registratie: Mei 2006
  • Laatst online: 15-09 21:49
Bedankt voor je nuttige informatie! ik ga me verdiepen in 'gdb'. Blijf het erg raar vinden desondanks, het is een vrij klein programmaatje en het enige wat ik doe is een kolom-file dumpen in een multidimensionale array.

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 21:24

.oisyn

Moderator Devschuur®

Demotivational Speaker

post eens code dan :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • leuk_he
  • Registratie: Augustus 2000
  • Laatst online: 15-07 15:35

leuk_he

1. Controleer de kabel!

core dump?

core inladen in debugger en een stack trace doen levert wellicht een logische plaats op waar het chrasht.

http://www.ffnn.nl/pages/...db-gnu-debugger-intro.php

Need more data. We want your specs. Ik ben ook maar dom. anders: forum, ff reggen, ff topic maken
En als je een oplossing hebt gevonden laat het ook ujb ff in dit topic horen.


Acties:
  • 0 Henk 'm!

  • roedi06
  • Registratie: Mei 2006
  • Laatst online: 15-09 21:49
Het gaat om de volgende code. Er is meer, maar hier gaat ie al op mis.

C: test.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#define DEG2RAD     (0.017453293)  /*Degrees to radians.*/
#define RAD2DEG     (57.29578)     /*Radians to degrees.*/
#define RAD_EARTH   (6371.0)          /*Radius of the earth*/
#define PI        (3.14159)    /*PI*/
#define LSTR        (2128)          /*Length of all strings used.*/
#define NTRACK      (22000)    /*Length array buls*/
#define KT        (1.94384449)   /*1 m/s is this amount of kts*/
#define SQUARE(x)   ((x)*(x))

int main(int argc, char *argv[])
{
/*COMMON VARIABLES*/
char *infile,line[LSTR];

FILE *fp;

if (argc<6) {
       printf("Usage: %s <file> <regio> <kolomX_model> <kolomY_avw> <kolomZ_bul>!\n\n",argv[0]);
       exit(1);
}


/*Reading outputdata.*/
int regio,kolomX,kolomY,kolomZ;
infile=argv[1];
sscanf(argv[2],"%d",&regio);
sscanf(argv[3],"%d",&kolomX);
sscanf(argv[4],"%d",&kolomY);
sscanf(argv[5],"%d",&kolomZ);
/*Opening of input file.*/

fp=fopen(infile,"r");
if (fp==NULL) {
  printf("Provided file does not exist or could not be opened!\n");
  printf("Please read instructions above and try again!");
  printf("");
  exit(2);
             }

int Ntrk=0,n;
int t1,t2,t3,t4,t17;
float t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33,t34,t35,t36,t37;
int t1_array[NTRACK],t2_array[NTRACK],t3_array[NTRACK],t4_array[NTRACK],t17_array[NTRACK];
float t5_array[NTRACK],t6_array[NTRACK],t7_array[NTRACK],t8_array[NTRACK],t9_array[NTRACK],t10_array[NTRACK];
float t11_array[NTRACK],t12_array[NTRACK],t13_array[NTRACK],t14_array[NTRACK],t15_array[NTRACK],t16_array[NTRACK];
float t18_array[NTRACK],t19_array[NTRACK],t20_array[NTRACK],t21_array[NTRACK],t22_array[NTRACK],t23_array[NTRACK];
float t24_array[NTRACK],t25_array[NTRACK],t26_array[NTRACK],t27_array[NTRACK],t28_array[NTRACK],t29_array[NTRACK];
float t30_array[NTRACK],t31_array[NTRACK],t32_array[NTRACK],t33_array[NTRACK],t34_array[NTRACK],t35_array[NTRACK];
float t36_array[NTRACK],t37_array[NTRACK];

while (fgets(line,sizeof(line),fp)) {
       sscanf(line,"%d %d %d %d %f %f %f %f %f %f %f %f %f %f %f %f %d %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f",&t1,&t2,&t3,&t4,&t5,&t6,&t7,&t8,&t9,&t10,&t11,&t12,&t13,&t14,&t15,&t16,&t17,&t18,&t19,&t20,&t21,&t22,&t23,&t24,&t25,&t26,&t27,&t28,&t29,&t30,&t31,&t32,&t33,&t34,&t35,&t36,&t37);
       t1_array[Ntrk]       =      t1;
       t2_array[Ntrk]       =      t2;
       t3_array[Ntrk]       =      t3;
       t4_array[Ntrk]       =      t4;
       t5_array[Ntrk]       =      t5;
       t6_array[Ntrk]       =      t6;
       t7_array[Ntrk]       =      t7;
       t8_array[Ntrk]       =      t8;
       t9_array[Ntrk]       =      t9;
       t10_array[Ntrk]      =      t10;
       t11_array[Ntrk]      =      t11;
       t12_array[Ntrk]      =      t12;
       t13_array[Ntrk]      =      t13;
       t14_array[Ntrk]      =      t14;
       t15_array[Ntrk]      =      t15;
       t16_array[Ntrk]      =      t16;
       t17_array[Ntrk]      =      t17;
       t18_array[Ntrk]      =      t18;
       t19_array[Ntrk]      =      t19;
       t20_array[Ntrk]      =      t20;
       t21_array[Ntrk]      =      t21;
       t22_array[Ntrk]      =      t22;
       t23_array[Ntrk]      =      t23;
       t24_array[Ntrk]      =      t24;
       t25_array[Ntrk]      =      t25;
       t26_array[Ntrk]      =      t26;
       t27_array[Ntrk]      =      t27;
       t28_array[Ntrk]      =      t28;
       t29_array[Ntrk]      =      t29;
       t30_array[Ntrk]      =      t30;
       t31_array[Ntrk]      =      t31;
       t32_array[Ntrk]      =      t32;
       t33_array[Ntrk]      =      t33;
       t34_array[Ntrk]      =      t34;
       t35_array[Ntrk]      =      t35;
       t36_array[Ntrk]      =      t36;
       t37_array[Ntrk]      =      t37;
       Ntrk++;
       }
fclose(fp);

//vullen in multi-dimensionale array >>>BEGIN<<<
float multi_dim_array[Ntrk-1][37];
int i,j;
for(i=0 ; i<Ntrk ; i++) {
       for(j=1 ; j<38 ; j++)       {
              //if(j==1){multi_dim_array[i][j]=t1_array[i];}
              //if(j==1){printf("%d\t%.0f\n",t1_array[i],multi_dim_array[i][j]);}
              if(j==2){multi_dim_array[i][j]= t2_array[i];}
              if(j==3){multi_dim_array[i][j]= t3_array[i];}
              if(j==4){multi_dim_array[i][j]= t4_array[i];}
              if(j==5){multi_dim_array[i][j]= t5_array[i];}
              if(j==6){multi_dim_array[i][j]= t6_array[i];}
              if(j==7){multi_dim_array[i][j]= t7_array[i];}
              if(j==8){multi_dim_array[i][j]= t8_array[i];}
              if(j==9){multi_dim_array[i][j]= t9_array[i];}
              if(j==10){multi_dim_array[i][j]= t10_array[i];}
              if(j==11){multi_dim_array[i][j]= t11_array[i];}
              if(j==12){multi_dim_array[i][j]= t12_array[i];}
              if(j==13){multi_dim_array[i][j]= t13_array[i];}
              if(j==14){multi_dim_array[i][j]= t14_array[i];}
              if(j==15){multi_dim_array[i][j]= t15_array[i];}
              if(j==16){multi_dim_array[i][j]= t16_array[i];}
              if(j==17){multi_dim_array[i][j]= t17_array[i];}
              if(j==18){multi_dim_array[i][j]= t18_array[i];}
              if(j==19){multi_dim_array[i][j]= t19_array[i];}
              if(j==20){multi_dim_array[i][j]= t20_array[i];}
              if(j==21){multi_dim_array[i][j]= t21_array[i];}
              if(j==22){multi_dim_array[i][j]= t22_array[i];}
              if(j==23){multi_dim_array[i][j]= t23_array[i];}
              if(j==24){multi_dim_array[i][j]= t24_array[i];}
              if(j==25){multi_dim_array[i][j]= t25_array[i];}
              if(j==26){multi_dim_array[i][j]= t26_array[i];}
              if(j==27){multi_dim_array[i][j]= t27_array[i];}
              if(j==28){multi_dim_array[i][j]= t28_array[i];}
              if(j==29){multi_dim_array[i][j]= t29_array[i];}
              if(j==30){multi_dim_array[i][j]= t30_array[i];}
              if(j==31){multi_dim_array[i][j]= t31_array[i];}
              if(j==32){multi_dim_array[i][j]= t32_array[i];}
              if(j==33){multi_dim_array[i][j]= t33_array[i];}
              if(j==34){multi_dim_array[i][j]= t34_array[i];}
              if(j==35){multi_dim_array[i][j]= t35_array[i];}
              if(j==36){multi_dim_array[i][j]= t36_array[i];}
              if(j==37){multi_dim_array[i][j]= t37_array[i];}
              }
}
//vullen in multi-dimensionale array >>>EINDE<<<

int regelcount=9999;
int reg1_start,reg2_start,reg3_start,reg4_start,reg5_start;
int reg1_stop,reg2_stop,reg3_stop,reg4_stop,reg5_stop;
for (n=0;n<Ntrk;n++){
       if(t1_array[n]==20050401 || t1_array[n]==20060401 || t1_array[n]==20070407 || t1_array[n]==20080403 || t1_array[n]==20090401){
              if(regelcount==9999 && t2_array[n]==1){reg1_start=n;
              regelcount=1;
              continue;}
              if(regelcount==1 && t2_array[n]==2 && t1_array[n+1]!=t1_array[n]){reg1_stop=(n-1);
              reg2_start=n;
              regelcount=2;
              continue;}
              if(regelcount==2 && t2_array[n]==3 && t1_array[n+1]!=t1_array[n]){reg2_stop=(n-1);
              reg3_start=n;
              regelcount=3;
              continue;}
              if(regelcount==3 && t2_array[n]==4 && t1_array[n+1]!=t1_array[n]){reg3_stop=(n-1);
              reg4_start=n;
              regelcount=4;
              continue;}
              if(regelcount==4 && t2_array[n]==5 && t1_array[n+1]!=t1_array[n]){reg4_stop=(n-1);
              reg5_start=n;
              reg5_stop=Ntrk-1;}
                     }
              }

int regio_regelnummers[5][2];
regio_regelnummers[1][0]=reg1_start;
regio_regelnummers[1][1]=reg1_stop;
regio_regelnummers[2][0]=reg2_start;
regio_regelnummers[2][1]=reg2_stop;
regio_regelnummers[3][0]=reg3_start;
regio_regelnummers[3][1]=reg3_stop;
regio_regelnummers[4][0]=reg4_start;
regio_regelnummers[4][1]=reg4_stop;
regio_regelnummers[5][0]=reg5_start;
regio_regelnummers[5][1]=reg5_stop;

printf("%d\t%d\n%d\t%d\n%d\t%d\n%d\t%d\n%d\t%d\n",regio_regelnummers[1][0],regio_regelnummers[1][1],regio_regelnummers[2][0],regio_regelnummers[2][1],regio_regelnummers[3][0],regio_regelnummers[3][1],regio_regelnummers[4][0],regio_regelnummers[4][1],regio_regelnummers[5][0],regio_regelnummers[5][1]);

int Number_of_pairs;
Number_of_pairs=(regio_regelnummers[regio][1]-regio_regelnummers[regio][0])+1;
printf("regio: %d\tNumb: %d\n",regio,Number_of_pairs);

exit(0);
}

Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 00:02
Je realiseert je blijkbaar niet dat in C een array met N elementen weliswaar met 0 tot en met N-1 geïndiceerd wordt, maar je die nog wel met grootte N moet declareren (dus niet N-1!). Je declareert nu al je arrays dus één te kort, en daardoor overflow je van alles. Dit zijn overigens fouten die je uitstekend kunt vinden met mudflap.

Mooie implementatie van het FOR-CASE idioom in die lus trouwens. :P

[ Voor 58% gewijzigd door Soultaker op 26-03-2010 19:59 ]


Acties:
  • 0 Henk 'm!

  • roedi06
  • Registratie: Mei 2006
  • Laatst online: 15-09 21:49
Soultaker schreef op vrijdag 26 maart 2010 @ 19:52:
Je realiseert je blijkbaar niet dat in C een array met N elementen weliswaar met 0 tot en met N-1 geïndiceerd wordt, maar je die nog wel met grootte N moet declareren (dus niet N-1!). Je declareert nu al je arrays dus één te kort, en daardoor overflow je van alles. Dit zijn overigens fouten die je uitstekend kunt vinden met mudflap.

Mooie implementatie van het FOR-CASE idioom in die lus trouwens. :P
Thanks, dat was het inderdaad. De array's waren in alle gevallen 1 te weinig. Beginnersfout ;) tijd niet meer met C gewerkt en dan ben je dat soort dingen weer kwijt... Bedankt, ben nu iig weer stukken verder met debuggen door jullie tips!

Acties:
  • 0 Henk 'm!

  • Mijzelf
  • Registratie: September 2004
  • Niet online
Je hebt het al opgelost, maar het eerste waar ik aan dacht toen ik je code zag was stack-overflow. Snel even uitgerekend gebruik je 2 * 37 * 22000 * sizeof(float) bytes stackruimte, dat komt neer op ongeveer 6,5 MB. Ik heb geen idee wat de limieten zijn, maar dat vind ik veel.

Acties:
  • 0 Henk 'm!

  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

default heb je in linux een 8MB stack.

ASSUME makes an ASS out of U and ME


Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 00:02
Het gaat dus net goed, maar op zich is het wel een aandachtspuntje. Vele megabytes aan data alloceren op de stack is af te raden, zeker als je (zoals hier) afhankelijk bent van een compiler constante als NTRACK. Stel dat je die later een keer wil ophogen, dan kom je vrijwel zeker in de problemen, terwijl je die grote matrix net zo goed uit de heap kunt alloceren, en dan kan 'ie in principe onbeperkt groeien.
Pagina: 1