Forum: Mikrocontroller und Digitale Elektronik Überlauf, nur wo?


von olpo (Gast)


Lesenswert?

Hallo,

ich habe eine Überlauf und bekomme den nicht weg.
Mein Programm ist ca. 1000 Zeilen groß. Allerdings läuft das Programm 
nicht lange, nach wenigen Funktionen ist schluss.
Ich habe alle malloc()'s wieder ge-free()'d. Das sind auch nur kleine 
malloc()'s von höchstens 20Byte, und auch nur wenige an der Zahl.

Hier ein bißchen Code, was passiert:
1
NODE global_node;
2
3
void rotz(){
4
5
  NODE* local_node;
6
7
  local_node = &global_node;
8
9
  printf("globus %x  locus %x, &global_node,local_node);

Beim ersten Mal geht noch alles gut. Nach einer Zeit rufe ich die 
Funktion wieder auf, und die Ausgaben der Adresse von locus ist für'n 
Lokus.
Die Adresse von global_node stimmt hingegen immer noch.
Die Adresse von local_node ist ganz klein ( 0x20), während die von 
global_node groß ist, 0x453453 (oder so).

Also, Überlauf, oder?

Aber am Heap kann's nicht liegen. Egal ob der "nur" 0x400 Byte oder 
0x5'000
Byte groß ist. Immer spinnt der an der selben Stelle. Auch die 
Stack-Größe ändern bringt nichts.

Tja, ich weiß nicht weiter. Ich sitze schon seit sieben Stunden daran.


Mein Projekt:
  Xilinx
  Microblaze
  BRAM 0x10'000
  Standalone oder Xilkernel ( beides gleicher Fehler)
  C-Code

von Karl H. (kbuchegg)


Lesenswert?

Überprüf mal alle deine Arrayzugriffe ob du irgendwo Out Of Bounds 
schreibst.

von olpo (Gast)


Lesenswert?

Na gut, werde gucken;

aber kann das wirklich sein?

Da läuft kein Thread oder so, sondern alles schön iterativ. Und die 
beiden Zeilen stehen direkt untereinander. Wie kann denn eine Zuweisung 
schiefgehen?
1
local_node = &global_node;
2
  printf("globus %x  locus %x", &global_node, local_node);

von Joachim D. (Firma: JDCC) (scheppertreiber)


Lesenswert?

Verwende doch mal %p anstatt %x, poste mal die Werte vom ersten
Durchlauf und dem wo es klemmt.

von Karl H. (kbuchegg)


Lesenswert?

olpo schrieb:

> Da läuft kein Thread oder so, sondern alles schön iterativ. Und die
> beiden Zeilen stehen direkt untereinander. Wie kann denn eine Zuweisung
> schiefgehen?

Dein eigentliches Problem sitzt ganz woanders.
Was du siehst sind die Symptome, aber nicht die Ursachen.

von Joachim D. (Firma: JDCC) (scheppertreiber)


Lesenswert?

local_node = &global_node;
 printf("globus %x  locus %x, &global_node,local_node);

Eigentlich müßten ja beide Werte gleich sein. Denkbar, daß %x auf
dem System eben nicht der Wert des kompletten Pointers ist.

Außerdem fehlt ein Hühnerfuß, das kann so nicht mal kompiliert werden.

von olpo (Gast)


Lesenswert?

ich glaube %p kann xil_printf nicht.
Aber, wenn ich stattdessen printf() verwende, bekomme ich eine schöne 
Fehlermeldung:
1
c:\xilinx\13.3_3\sdk\sdk\gnu\microblaze\nt64\bin\..\lib\gcc\microblaze-xilinx-elf\4.1.2\..\..\..\..\microblaze-xilinx-elf\bin\ld.exe: section .ctors [000000b0 -> 000000b7] overlaps section .text [00000050 -> 0001445b]
Kann es sein, dass .text zur Laufzeit überläuft?

Wenn ja, wie kann ich die Größe von .text ändern? Einfach den Heap 
verkleinern reicht nicht, wie ich ausprobiert habe.

Hier das Kauderwelsch von LinkScript
1
/*******************************************************************/
2
/*                                                                 */
3
/* This file is automatically generated by linker script generator.*/
4
/*                                                                 */
5
/* Version: Xilinx EDK 13.3 EDK_O.76xd                                */
6
/*                                                                 */
7
/* Copyright (c) 2010 Xilinx, Inc.  All rights reserved.           */
8
/*                                                                 */
9
/* Description : MicroBlaze Linker Script                          */
10
/*                                                                 */
11
/*******************************************************************/
12
13
_STACK_SIZE = DEFINED(_STACK_SIZE) ? _STACK_SIZE : 0x400;
14
_HEAP_SIZE = DEFINED(_HEAP_SIZE) ? _HEAP_SIZE : 0x400;
15
16
/* Define Memories in the system */
17
18
MEMORY
19
{
20
   ilmb_cntlr_CI_dlmb_cntlr_CI : ORIGIN = 0x00000050, LENGTH = 0x0000FFB0
21
   DDR2_SDRAM_MPMC_BASEADDR : ORIGIN = 0x90000000, LENGTH = 0x10000000
22
}
23
24
/* Specify the default entry point to the program */
25
26
ENTRY(_start)
27
28
/* Define the sections, and where they are mapped in memory */
29
30
SECTIONS
31
{
32
.vectors.reset 0x00000000 : {
33
   *(.vectors.reset)
34
} 
35
36
.vectors.sw_exception 0x00000008 : {
37
   *(.vectors.sw_exception)
38
} 
39
40
.vectors.interrupt 0x00000010 : {
41
   *(.vectors.interrupt)
42
} 
43
44
.vectors.hw_exception 0x00000020 : {
45
   *(.vectors.hw_exception)
46
} 
47
48
.text : {
49
   *(.text)
50
   *(.text.*)
51
   *(.gnu.linkonce.t.*)
52
} > ilmb_cntlr_CI_dlmb_cntlr_CI
53
54
.init : {
55
   KEEP (*(.init))
56
} > ilmb_cntlr_CI_dlmb_cntlr_CI
57
58
.fini : {
59
   KEEP (*(.fini))
60
} > ilmb_cntlr_CI_dlmb_cntlr_CI
61
62
.ctors : {
63
   __CTOR_LIST__ = .;
64
   ___CTORS_LIST___ = .;
65
   KEEP (*crtbegin.o(.ctors))
66
   KEEP (*(EXCLUDE_FILE(*crtend.o) .ctors))
67
   KEEP (*(SORT(.ctors.*)))
68
   KEEP (*(.ctors))
69
   __CTOR_END__ = .;
70
   ___CTORS_END___ = .;
71
} > ilmb_cntlr_CI_dlmb_cntlr_CI
72
73
.dtors : {
74
   __DTOR_LIST__ = .;
75
   ___DTORS_LIST___ = .;
76
   KEEP (*crtbegin.o(.dtors))
77
   KEEP (*(EXCLUDE_FILE(*crtend.o) .dtors))
78
   KEEP (*(SORT(.dtors.*)))
79
   KEEP (*(.dtors))
80
   __DTOR_END__ = .;
81
   ___DTORS_END___ = .;
82
} > ilmb_cntlr_CI_dlmb_cntlr_CI
83
84
.rodata : {
85
   __rodata_start = .;
86
   *(.rodata)
87
   *(.rodata.*)
88
   *(.gnu.linkonce.r.*)
89
   __rodata_end = .;
90
} > ilmb_cntlr_CI_dlmb_cntlr_CI
91
92
.sdata2 : {
93
   . = ALIGN(8);
94
   __sdata2_start = .;
95
   *(.sdata2)
96
   *(.sdata2.*)
97
   *(.gnu.linkonce.s2.*)
98
   . = ALIGN(8);
99
   __sdata2_end = .;
100
} > ilmb_cntlr_CI_dlmb_cntlr_CI
101
102
.sbss2 : {
103
   __sbss2_start = .;
104
   *(.sbss2)
105
   *(.sbss2.*)
106
   *(.gnu.linkonce.sb2.*)
107
   __sbss2_end = .;
108
} > ilmb_cntlr_CI_dlmb_cntlr_CI
109
110
.data : {
111
   . = ALIGN(4);
112
   __data_start = .;
113
   *(.data)
114
   *(.data.*)
115
   *(.gnu.linkonce.d.*)
116
   __data_end = .;
117
} > ilmb_cntlr_CI_dlmb_cntlr_CI
118
119
.got : {
120
   *(.got)
121
} > ilmb_cntlr_CI_dlmb_cntlr_CI
122
123
.got1 : {
124
   *(.got1)
125
} > ilmb_cntlr_CI_dlmb_cntlr_CI
126
127
.got2 : {
128
   *(.got2)
129
} > ilmb_cntlr_CI_dlmb_cntlr_CI
130
131
.eh_frame : {
132
   *(.eh_frame)
133
} > ilmb_cntlr_CI_dlmb_cntlr_CI
134
135
.jcr : {
136
   *(.jcr)
137
} > ilmb_cntlr_CI_dlmb_cntlr_CI
138
139
.gcc_except_table : {
140
   *(.gcc_except_table)
141
} > ilmb_cntlr_CI_dlmb_cntlr_CI
142
143
.sdata : {
144
   . = ALIGN(8);
145
   __sdata_start = .;
146
   *(.sdata)
147
   *(.sdata.*)
148
   *(.gnu.linkonce.s.*)
149
   __sdata_end = .;
150
} > ilmb_cntlr_CI_dlmb_cntlr_CI
151
152
.sbss : {
153
   . = ALIGN(4);
154
   __sbss_start = .;
155
   *(.sbss)
156
   *(.sbss.*)
157
   *(.gnu.linkonce.sb.*)
158
   . = ALIGN(8);
159
   __sbss_end = .;
160
} > ilmb_cntlr_CI_dlmb_cntlr_CI
161
162
.tdata : {
163
   __tdata_start = .;
164
   *(.tdata)
165
   *(.tdata.*)
166
   *(.gnu.linkonce.td.*)
167
   __tdata_end = .;
168
} > ilmb_cntlr_CI_dlmb_cntlr_CI
169
170
.tbss : {
171
   __tbss_start = .;
172
   *(.tbss)
173
   *(.tbss.*)
174
   *(.gnu.linkonce.tb.*)
175
   __tbss_end = .;
176
} > ilmb_cntlr_CI_dlmb_cntlr_CI
177
178
.bss : {
179
   . = ALIGN(4);
180
   __bss_start = .;
181
   *(.bss)
182
   *(.bss.*)
183
   *(.gnu.linkonce.b.*)
184
   *(COMMON)
185
   . = ALIGN(4);
186
   __bss_end = .;
187
} > ilmb_cntlr_CI_dlmb_cntlr_CI
188
189
_SDA_BASE_ = __sdata_start + ((__sbss_end - __sdata_start) / 2 );
190
191
_SDA2_BASE_ = __sdata2_start + ((__sbss2_end - __sdata2_start) / 2 );
192
193
/* Generate Stack and Heap definitions */
194
195
.heap : {
196
   . = ALIGN(8);
197
   _heap = .;
198
   _heap_start = .;
199
   . += _HEAP_SIZE;
200
   _heap_end = .;
201
} > ilmb_cntlr_CI_dlmb_cntlr_CI
202
203
.stack : {
204
   _stack_end = .;
205
   . += _STACK_SIZE;
206
   . = ALIGN(8);
207
   _stack = .;
208
   __stack = _stack;
209
} > ilmb_cntlr_CI_dlmb_cntlr_CI
210
211
_end = .;
212
}

von Joachim D. (Firma: JDCC) (scheppertreiber)


Lesenswert?

Meinst DU hilft uns besser wie der Quellcode ?
Du hast den ja sogar falsch abgetippt ;)

von olpo (Gast)


Lesenswert?

1
typedef struct resource_NODE{
2
  Xuint32 resource_id;
3
  Xuint8  t_c_id;
4
  struct tcid_NODE* connected_tcids;
5
  Xuint8* session_list;
6
  Xuint32 session_list_size;
7
  struct resource_NODE* next;
8
}resource_NODE;
9
10
11
resource_NODE resource_list = {0, 0, NULL, 0, NULL};
12
13
14
Xuint8 setSession( Xuint32 resource_id, Xuint16* session_nb, Xuint8 tc_id ){
15
16
    int i;
17
    *session_nb = 1;
18
19
    resource_NODE* resource;
20
21
    resource->next = &resource_list;
22
    xil_printf("next %x &resource_list %x\n\r",resource->next, &resource_list);
23
24
  while( resource->next != NULL){
25
...

von Karl H. (kbuchegg)


Lesenswert?

olpo schrieb:

>     resource_NODE* resource;
>
>     resource->next = &resource_list;

Autsch.

Nun hab dich nicht so. Willst du deinen Fehler finden oder nicht? SOllen 
wir dir dabei helfen oder nicht?

Wenn du beide Fragen mit 'Ja' beantwortest, dann hör auf hier 
Phantasiecode zu posten, der voller Fehler ist. Hier hat nämlich keiner 
Lust, Phantomfehlern nachzulaufen.

Und wenn das da tatsächlich der Anfang der Funktion ist, dann wundert 
mich nichts mehr. Schnelle Frage: Auf welches resource_NODE element 
zeigt denn der Pointer resource, dessen next Feld du veränderst?

von Rolf M. (rmagnus)


Lesenswert?

olpo schrieb:
> resource_NODE* resource;

Hier hast du einen Zeiger, den du nicht initialisierst.

>     resource->next = &resource_list;

Hier dereferenzierst du ihn. Du schreibst "in die Pampa".

von olpo (Gast)


Lesenswert?

Hups...ist kein Fantasie-Code. Ich bin so.. :)

So besser?
1
resource_NODE resource;
2
3
resource.next = &resource_list;

von Karl H. (kbuchegg)


Lesenswert?

olpo schrieb:
> Hups...ist kein Fantasie-Code. Ich bin so.. :)
>
> So besser?
kommt drauf an wies weitergeht.

Was wird das hier: Programmieren per Ratespiel?

von Joachim D. (Firma: JDCC) (scheppertreiber)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Was wird das hier: Programmieren per Ratespiel?

Sieht so aus ;)

Es gibt auch bei C manchmal ganz nette Seiteneffekte. Das sieht man
leider nur im Zusammenhang. Den Codeschnippseln nach frißt das eh
kein Compiler ...

von Karl H. (kbuchegg)


Lesenswert?

Joachim Drechsel schrieb:
> Karl Heinz Buchegger schrieb:
>> Was wird das hier: Programmieren per Ratespiel?
>
> Sieht so aus ;)

Ich nehm den 50:50 Joker

> Es gibt auch bei C manchmal ganz nette Seiteneffekte. Das sieht man
> leider nur im Zusammenhang. Den Codeschnippseln nach frißt das eh
> kein Compiler ...

Den Codeschnipseln nach würd ich dem TO dringend ein paar 
Trainingseinheiten zum Thema "dynamic data structures" auf dem PC 
empfehlen. Mit besonderem Augenmerk auf penibler NULL-Initialisierung 
ausnahmslos ALLER Pointer.

von olpo (Gast)


Lesenswert?

Jaja, amüsiert euch nur...

Wie ist das bei malloc()?

Das liefert ja auch nur einen Pointer zurück. Kann ich das dann gleich 
nutzen, oder muss ich das zuerst auch mit "was konkreten" füllen?

Also,
1
struct struktur{
2
  int a;
3
  int b;
4
};
5
6
void bla(){
7
8
  struktur* s = malloc(sizeof(struktur));
9
10
/* dann sollte ich das wohl nicht machen */
11
12
  s->a = 1234;
13
14
/* sondern zuerst initialisieren? */
15
16
  struktur init;
17
18
  *s = init;
19
20
  init.a = 1234;

von Karl H. (kbuchegg)


Lesenswert?

olpo schrieb:
> Jaja, amüsiert euch nur...

Wir amüsieren uns nicht.
Ganz im Gegenteil.

> Wie ist das bei malloc()?

Es liefert einen Pointer auf einen entsprechend großen Speicherbereich.

> Das liefert ja auch nur einen Pointer zurück. Kann ich das dann gleich
> nutzen, oder muss ich das zuerst auch mit "was konkreten" füllen?

Da fehlts jetzt aber arg weit.

> Also,
> [c]struct struktur{
>   int a;
>   int b;
> };
>
> void bla(){
>
>   struktur* s = malloc(sizeof(struktur));
>
> /* dann sollte ich das wohl nicht machen */
>
>   s->a = 1234;

doch, das ist fein.
Du hast einen Pointer und der zeigt auf Speicher in dem ein struktur 
Objekt existiert.

>
> /* sondern zuerst initialisieren? */
>
>   struktur init;

Und wie machst du die Initialisierung?
Richtig. Mit Zuweisungen. Womit wir wieder bei der Variante 1 wären.

>   *s = init;

Das ist auch nichts anderes als eine Zuweisung. Nur dass du eine 
komplette Struktur in einem Rutsch auf den Speicher kopierst wo der 
Zeiger hinzeigt und in der Variante 1 kopierst du in Häppchen Member für 
Member.

von Peter D. (peda)


Lesenswert?

olpo schrieb:
> Ich habe alle malloc()'s wieder ge-free()'d. Das sind auch nur kleine
> malloc()'s von höchstens 20Byte

Ich kann mir nicht vorstellen, daß das mächtige malloc-Geschütz für nur 
einige 20Byte überhaupt einen Sinn macht.
Warum kannst Du die Variablen nicht einfach schon zur Compilezeit 
reservieren?

Nicht alle Techniken, die auf einem PC mit vielen GB RAM Sinn machen, 
muß man auch einem MC aufzwingen.

20 Byte würde allerdings auch auf dem PC niemand mit malloc anlegen. Der 
Verwaltungsaufwand wird schon ein Mehrfaches betragen. Häppchen unter 
1kB lohnen sich dann nicht.


Peter

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.