Forum: Mikrocontroller und Digitale Elektronik Codegröße Fehlerbehandlung/Exceptions (C++)


von FelixW (Gast)


Lesenswert?

Hallo Leute,

Folgendes Problem (C++, Newlib vorkompiliert, LPCXpresso, 
-fno-exceptions ):
erstelle ich ein Objekt mit "new" (oder ich definiere eine abstrakte 
Funktion -> mit Workaround gelöst)
so erhöht sich die Codegröße um ca. 70kB.

Anscheinend werden Routinen für eine Fehlerausgabe(Exceptions) 
eingebunden (printf, strcmp, __write, etc.)

Ich bräuchte Tipps, die Fehlerausgabe umzuleiten und selber zu 
behandeln, sodass der Code sich nicht so aufbläht?
Insbesondere "__cxa_demangle" ist über 40kB groß.

Danke Felix

Auszüge aus dem map-File (hoffentlich habe ich was verwertbares 
rausgesucht):
1
                              c:/nxp/lpcxpresso_5.2.4_2122/lpcxpresso/tools/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib/armv7-m\libstdc++.a(bad_alloc.o) (std::exception::~exception())
2
c:/nxp/lpcxpresso_5.2.4_2122/lpcxpresso/tools/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib/armv7-m\libstdc++.a(del_op.o)
3
4
                              c:/nxp/lpcxpresso_5.2.4_2122/lpcxpresso/tools/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib/armv7-m\libstdc++.a(vterminate.o) (__cxa_current_exception_type)
5
c:/nxp/lpcxpresso_5.2.4_2122/lpcxpresso/tools/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib/armv7-m\libstdc++.a(pointer_type_info.o)
6
7
c:/nxp/lpcxpresso_5.2.4_2122/lpcxpresso/tools/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib/armv7-m\libstdc++.a(cp-demangle.o)
8
                              c:/nxp/lpcxpresso_5.2.4_2122/lpcxpresso/tools/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib/armv7-m\libstdc++.a(vterminate.o) (__cxa_demangle)
9
10
                              c:/nxp/lpcxpresso_5.2.4_2122/lpcxpresso/tools/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib/armv7-m\libstdc++.a(cp-demangle.o) (realloc)
11
c:/nxp/lpcxpresso_5.2.4_2122/lpcxpresso/tools/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib/armv7-m\libc.a(lib_a-strncmp.o)
12
                              c:/nxp/lpcxpresso_5.2.4_2122/lpcxpresso/tools/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib/armv7-m\libstdc++.a(cp-demangle.o) (strncmp)
13
14
                              c:/nxp/lpcxpresso_5.2.4_2122/lpcxpresso/tools/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib/armv7-m\libstdc++.a(cp-demangle.o) (memcmp)
15
c:/nxp/lpcxpresso_5.2.4_2122/lpcxpresso/tools/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib/armv7-m\libc.a(lib_a-putc.o)
16
17
18
19
.text          0x00008200     0x9940 c:/nxp/lpcxpresso_5.2.4_2122/lpcxpresso/tools/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib/armv7-m\libstdc++.a(cp-demangle.o)
20
                0x00011a58                __cxa_demangle
21
                0x00011b1c                __gcclibcxx_demangle_callback

von Hannes W. (hannes_w)


Lesenswert?

Schließt sich
> -fno-exceptions ):
und
> Fehlerausgabe(Exceptions)
nicht aus?

Was genau machst du?

Die Map-File nützt nix. Wenn etwas Code zu sehen wäre, müsste man nicht 
raten.
Willst du nun Exceptions oder nicht? Wenn ja, musst du mit dem Overhead 
leben. Wenn nicht, dann musst/kannst du sie auch nicht behandeln.
Ansonsten kann ich dich noch auf -fno-rtti hinweisen, falls das bei dir 
anwendbar ist.

von FelixW (Gast)


Lesenswert?

> Schließt sich
> > -fno-exceptions ):
> und
> > Fehlerausgabe(Exceptions)
> nicht aus?

Anscheinend nicht. Meine Bibliothek ist als *.a vorkompiliert. 
Vermutlich ohne -fno-exceptions, -fno-rtti.

Compilerflag -fno-rtti ist gesetzt.

Beispiel A, 88kB im Flash; Ist mir zu groß (Kann nur bis 128kB debuggen)
Auf Exceptions kann ich verzichten, auf new möchte ich nur ungern 
verzichten. (Beispiel wird nicht so verwendet werden, da ziemlich 
sinnfrei ;) )
1
#include "ColorCIE.h"
2
3
int main(void) {
4
  setupHardware();
5
  ColorXYZ *col = new ColorXYZ();
6
  delete(col);
7
while(1);
8
}

Beispiel B, 11kB im Flash, schön klein, aber nur lokale Klasse
1
#include "ColorCIE.h"
2
3
int main(void) {
4
  setupHardware();
5
  ColorXYZ col = ColorXYZ();
6
while(1);
7
}

von Dr. Sommer (Gast)


Lesenswert?

FelixW schrieb:
> aber nur lokale Klasse
lokale Klassen gibts nicht, das ist eine lokale Variable, wenn schon.
In C++ schreibt man übrigens üblicherweise "ColorXYZ col ();". Das 
kannst du auch außerhalb einer Funktion schreiben, s.d. die Variable von 
überall zugreifbar wird.
Sicher dass du "new" brauchst (wofür genau?) und das nicht nur aus 
einem Verständnis-Mangel oder Java-Gewohnheiten resultiert ;-)
Das Problem ist dass "new" Exceptions wirft. Du müsstest die 
entsprechende Stelle deiner libc finden und durch einen Dummy ersetzen 
der zB "while(1);" macht anstelle der Exception...

von temp (Gast)


Lesenswert?

Also wenn man schon new und delete benutzt auf einem kleinen Controller, 
dann sollte man die entsprechenden Routinen auch selbst programmieren. 
Wer soll dir denn die Speicherverwaltung abnehmen? Die newlib? Die kennt 
weder deinen Controller noch deinen RAM. Hier muss was hin was der 
Aufgabenstellung angepasst ist, das kann keiner für dich entscheiden. 
Und wenn du nicht weißt wie das geht, dann sollte new und delete ein 
rotes Tuch für dich sein. Falls man FreeRtos verwendet kann es eine gute 
Idee sein sich an deren Speicherverwaltung mit dranzuhängen. 
Insbesondere wenn die neuere heap_4.c verwendet wird. Das sieht dann in 
etwa so aus:
1
// wird aus der Freertos Malloc Funktion gerufen
2
// wenn eine Speicheranforderung fehl schlägt
3
extern "C"
4
{
5
  void vApplicationMallocFailedHook( void )
6
   {
7
    while (1)
8
      {
9
      ;
10
      }
11
    }  
12
}    
13
14
// Abbildung der globalen new und delete-Handler
15
// auf die Malloc Funktionen von FreeRtos
16
// hier passiert auch die Verriegelung der Threads
17
void* operator new(size_t size)
18
{
19
  return pvPortMalloc(size);
20
}
21
22
void* operator new[](size_t size)
23
{
24
  return pvPortMalloc(size);
25
}
26
27
void  operator delete(void* pointer)
28
{
29
  vPortFree(pointer);
30
}
31
  
32
void  operator delete[](void* pointer)
33
{
34
  vPortFree(pointer);
35
}

von FelixW (Gast)


Lesenswert?

Danke. Genau so eine (einfache) Lösung habe ich mir gewünscht. :)

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.