Forum: Compiler & IDEs Aufrufende Funktion herausfinden


von Walter T. (nicolas)


Lesenswert?

Guten Abend zusammen,

ich bin in auf der Suche nach Flash-Flashfressern in einem Projekt 
(STM32F103). Ich habe mir mal mit nm die Funktionen angeschaut, die nach 
der LTO noch übrig bleiben. Hier die größten Brocken:
1
134247197 00000856 T _realloc_r
2
134264961 00000988 T __ieee754_rem_pio2
3
536872084 00001032 D __malloc_av_
4
536871016 00001064 d impure_data
5
134239781 00001116 T _malloc_r
6
134224749 00001188 T main
7
134227809 00001300 T tft_putChar
8
134266733 00001684 T __kernel_rem_pio2
9
134232949 00001792 T RunAllTests
10
134256833 00002836 T _dtoa_r
11
134248293 00003952 T _svfprintf_r
12
134252245 00004016 T _vfprintf_r

Auffällig sind die beiden __ieee754_rem_pio2 und __kernel_rem_pio2. Zum 
einen benutze ich meines Wissens innerhalb des gesamten Projekts keine 
trigonometrischen Funktionen auf Float. Zum anderen scheint es eine 
Dublette für unterschiedliche Float-Varianten zu sein.

Gibt es eine Möglichkeit, herauszufinden, welche Kette von 
Funktionsaufrufen die Einbindung dieser Funktionen bewirkt?

Viele Grüße
W.T.

von M.K. B. (mkbit)


Lesenswert?

Wenn du auf dem Controller Debuggern kannst, dann wäre ein einfacher 
Versuch einen Breakpoint auf die Funktion zu setzen. Vielleicht wird die 
Funktion aufgerufen und du hast einen Callstack.

Alternativ könntest du für die Objectfiles die .lst Dateien durchsuchen, 
ob dort die entsprechende Funktion aufgerufen wird. Wenn die Funktion 
allerdings in einer Bibliothek, die du nur linkst, aufgerufen wird, dann 
kommst du damit wahrscheinlich nicht weiter.

Nachdem deine Liste "RunAllTests" enthält vermute ich, dass dort ein 
Testframework läuft. Könnte es sein, dass dort für eine Metrik oder zur 
Darstellung diese Funktionen benötigt werden?

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Walter T. schrieb:
> Guten Abend zusammen,
>
> ich bin in auf der Suche nach Flash-Flashfressern in einem Projekt
> (STM32F103). Ich habe mir mal mit nm die Funktionen angeschaut, die nach
> der LTO noch übrig bleiben. Hier die größten Brocken:
>
1
> 134247197 00000856 T _realloc_r
2
> 134264961 00000988 T __ieee754_rem_pio2
3
> 536872084 00001032 D __malloc_av_
4
> 536871016 00001064 d impure_data
5
> 134239781 00001116 T _malloc_r
6
> 134224749 00001188 T main
7
> 134227809 00001300 T tft_putChar
8
> 134266733 00001684 T __kernel_rem_pio2
9
> 134232949 00001792 T RunAllTests
10
> 134256833 00002836 T _dtoa_r
11
> 134248293 00003952 T _svfprintf_r
12
> 134252245 00004016 T _vfprintf_r
13
>
>
> Zum einen benutze ich meines Wissens innerhalb des gesamten Projekts keine
> trigonometrischen Funktionen auf Float.

Da:

> 134248293 00003952 T _svfprintf_r
> 134252245 00004016 T _vfprintf_r

Dass die zur Laufzeit nicht verwendet werden kann ein Compiler nicht 
wissen — uns selbst wenn, welche xprintf-Implementation sollte er dann 
verwenden?  Manchmal gibt's abgespeckte LibCs mit weniger Features: 
Nicht Standard-konfirm aber eben kleiner.

> Zum anderen scheint es eine Dublette für unterschiedliche Float-Varianten zu 
sein.

???

> Gibt es eine Möglichkeit, herauszufinden, welche Kette von
> Funktionsaufrufen die Einbindung dieser Funktionen bewirkt?

Map-File oder Lib-Quelle.

von Purzel H. (hacky)


Lesenswert?

printf() ... was soll die bringen ? Auf dem PC etwas Tolles, auf einem 
Controller ein striktes No-go.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Zwölf M. schrieb:
> printf() ... was soll die bringen ? Auf dem PC etwas Tolles, auf einem
> Controller ein striktes No-go.

Im Allgemeinen ist das falsch. Auf 32-Bit-µCs (mit entsprechend mehr 
Flash/RAM) geht das durchaus. Auf einem STM32F103 ist das überhaupt kein 
Problem.

von Walter T. (nicolas)


Lesenswert?

Guten Morgen,

danke für die Antworten. Vorweg: Mir geht es momentan nicht ums Platz 
sparen. Mit dem Platz sieht es noch gut genug aus (ich habe noch 64 kB 
Reserve). Mir geht es darum, den Platzverbrauch zu verstehen.

M.K. B. schrieb:
> Nachdem deine Liste "RunAllTests" enthält vermute ich, dass dort ein
> Testframework läuft.

Richtig. Deswegen überhaupt die Float/Double-Unterstützung (Vergleich 
von selbstgeschriebenen Funktionen mit einer Referenzimplementierung) 
und Ausgabe per printf.

Eine Metrik gibt es aber nicht aus und wird m.W. auch nicht berechnet.

Johann L. schrieb:
> Da:
>
>> 134248293 00003952 T _svfprintf_r
>> 134252245 00004016 T _vfprintf_r

Das ist auch meine Vermutung. Mein Ziel ist der Schritt vom Vermuten zum 
Wissen. Ein bischen Abwegig ist es ja schon, daß printf() irgendwelche 
Bruchteile von PI benötigt.

Im *.res-File tauchen die Funktionen nicht auf- deswegen gehe ich davon 
aus, dass sie von Library-Funktionen aufgerufen werden.

Im Map-File sehe ich.... nichts. Außer dass alle "verdächtigen" 
Funktionen aus der libc stammen (libg_s.a). Aber so habe ich die 
richtigen Suchbegriffe gefunden (call graph + map file). Da muß ich mich 
mal in das passende Werkzeug einlesen. Ich dachte eventuell, so etwas 
wär schon in den Bordmitteln enthalten.

M.K. B. schrieb:
> Wenn du auf dem Controller Debuggern kannst, dann wäre ein einfacher
> Versuch einen Breakpoint auf die Funktion zu setzen.

Das war auch mein erster Gedanke. Aber wie setze ich einen Breakpoint in 
eine Library-Funktion, die als Kompilat verlinkt wird? Gibt es 
Debugging-Werkzeuge, die für die Arbeit mit einem reinen Binary ohne 
Quelltext geeignet sind? Bislang habe ich immer in der IDE debuggt.

Zwölf M. schrieb:
> printf() ... was soll die bringen ?

Damit kann ich den Inhalts meines mit malloc() allozierten Arrays aus 
zur Laufzeit berechneten double-Werten sehr bequem ausgeben. Was 
übrigens selbst auf dem AVR bei 1 MHz schneller geht, als eine 
Forendiskussion darüber zu lesen. BTDT.

von Rolf M. (rmagnus)


Lesenswert?

Frank M. schrieb:
> Zwölf M. schrieb:
>> printf() ... was soll die bringen ? Auf dem PC etwas Tolles, auf einem
>> Controller ein striktes No-go.
>
> Im Allgemeinen ist das falsch. Auf 32-Bit-µCs (mit entsprechend mehr
> Flash/RAM) geht das durchaus. Auf einem STM32F103 ist das überhaupt kein
> Problem.

Und selbst auf einem AVR würde ich das nicht einfach a priori 
ausschließen. Wenn man den Flash-Speicher nicht für was anderes braucht, 
und printf() nützlich sein kann, warum sollte man ihn dann ungenutzt 
lassen, nur um irgendeinem Prinzip zu gehorchen? Geld bekommt man dafür 
bekanntlich nicht zurück.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Walter T. schrieb:
> Im Map-File sehe ich.... nichts. Außer dass alle "verdächtigen"
> Funktionen aus der libc stammen (libg_s.a).

Da sollte doch zumindest das Modul autauchen? Hier mal einen Auszug (für 
anderes Target, was aber keine Rolle spielt):
1
Archive member included to satisfy reference by file (symbol)
2
3
.../bin/../lib/gcc/avr/8.0.1/avr5/libgcc.a(_exit.o)
4
                              .../bin/../lib/gcc/avr/8.0.1/../../../../avr/lib/avr5/crtatmega168.o (exit)

Von Modul crtatmega168.o wurde also Symbol "exit" referenziert, das noch 
nicht aufgelöst war.  Die Auflösung / Definition des Symbols "exit" 
geschah dadurch, dass gegen Modul _exit.o aus libgcc.a gelinkt wurde.

Einzelne Funktionen sieht man auf dieser Ebene nicht mehr, sondern nur 
noch Module oder Input-Sections.  Da libc/libm üblicherweise so 
übersetzt werden, dass jede Funktion in einem eigenen, entsprechend 
benannten Modul landet, kann man die Funktion hier einfach raten: Es ist 
_exit aus der libgcc.

Oder
1
$ target-nm ...libgcc.a | grep -A4 '^_exit.o'
2
_exit.o:
3
00000002 t __stop_program
4
00000000 T _exit
5
00000000 W exit

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Bei der newlib nano muss man floats beim printf explizit erlauben:

>2) Programs that require formatted floating-point input/output must >explicitly
>   reference the relevant support function during linking.  For the scanf()
>   family of routines the support function is "_scanf_float".  For the
>   printf() family of routines the support function is "_printf_float".
>   There are two ways to achieve this:
>   a) Explicitly reference the support function during linking.  For example,
>by adding "-u _printf_float" to the link command

Also vllt mal die libc wechseln?
Oder guck doch mal welche du nimmst, vllt lässts sich ja abschalten.

: Bearbeitet durch User
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.