printf modifizieren und stdout capturn

Dieses Thema im Forum "C/C++" wurde erstellt von mythos, 04.04.2010.

  1. mythos

    mythos Mitglied

    Dabei seit:
    20.09.2005
    Beiträge:
    27
    Zustimmungen:
    0
    Hallo,

    ich moechte das Verhalten aller *printf Funkionen modifizieren und zwar sollen diese statt auf stdout in char strings schreiben. Mit anderen Worten, ich will stdout capturn und in einem char* speichern.

    Mir ist klar, dass das Anliegen ein wenig sonderbar klingt. Stdout soll insbesondere nicht mit freopen in ein File umgeleitet und aus dem File wieder eingelesen werden. Ich verwende ein Testtool; sobald die Daten in Files geschrieben und wieder gelesen werden, verlassen sie den Scope ueber den das Testtool effektiv nachdenken kann.

    Die Fragen sind nun:
    a.) Gibt's einen besseren Weg mein Vorhaben anzugehen?
    b.) Ich will nicht alle *printf Funktionen neu schreiben muessen bzw. das Implementieren des Formatstring-Handling stell' ich mir recht unlustig vor. Existiert eine Art printf-Kernfunktion, die ich ersetzen kann, die Auswirkungen auf alle anderen hat? Welche?

    mythos
     
  2. Anzeige

    Schau dir mal diese Kategorie an. Dort findest du bestimmt etwas.
    Registrieren bzw. einloggen, um diese und auch andere Anzeigen zu deaktivieren
  3. ar0

    ar0 Jungspund

    Dabei seit:
    29.03.2010
    Beiträge:
    17
    Zustimmungen:
    0
    Nicht alle *printf Funktionen schreiben auf stdout. Kennst du snprintf?

    Weitere Frage: ist pipe() eine Möglichkeit?

    Ich würde dir sehr stark von diesem Vorhaben abraten (C Standard-Bibliothek um-/neuschreiben..).
     
  4. #3 mythos, 04.04.2010
    Zuletzt bearbeitet: 04.04.2010
    mythos

    mythos Mitglied

    Dabei seit:
    20.09.2005
    Beiträge:
    27
    Zustimmungen:
    0
    Hallo,

    Danke fuer deine Antwort.

    Klar. Fuer's erste reicht mir stdout.

    In der Tat. Das ist eine gute Idee. Ich muss das ausprobieren und melde mich wieder wenn es funktioniert bzw. nicht funktioniert.

    Auch das ist klar. Jeder vernuenftige Mensch wuerde das vermeiden wollen. Ich seh nur keine andere Moeglichkeit. Auf der anderen Seite ist ein Testsystem, das mit einer eigenen Dummy-Variante der Standard-Bibliothek arbeitet, nichts ungewoehnliches.

    mythos
    .
    .
    .
    EDIT (autom. Beitragszusammenführung) :
    .

    Hallo,

    Funktioniert zwar ohne Testtool, aber nicht mit.

    mythos
     
  5. ar0

    ar0 Jungspund

    Dabei seit:
    29.03.2010
    Beiträge:
    17
    Zustimmungen:
    0
    Ok, was "funktioniert", was hast du gemacht? Was "funktioniert nicht", kannst du ein Testprogramm mit Angabe von "was soll passieren" und "was passiert tatsächlich" angeben, vielleicht werden dann ja ein paar Sachen klarer (zumdindest für mich).

    Ich hab generell ein paar Probleme wenn ich dein ursprünglichen Post durchlese: wie genau soll in ein char Array geschrieben werden, weißt du im vornherein wieviel Output generiert werden wird? Oder soll der "stdout-string" dynamisch vergrößert werden?

    Das versteh ich nicht. Wie meinst du das, fürs erste reicht dir stdout?
    snprintf schreibt ja bereits in ein char Array. Dann müsstest du nur noch die Aufrufe von printf durch snprintf in deiner Anwendung "Austauschen" (und natürlich den Overhead für das string-management hinzufügen).
    Aber hier stellt sich natürlich auch die Frage, ob du überhaupt die Möglichkeit hast die printf-Aufrufe im Quelltext zu verändern oder ob du einfach nur "von außen" auf stdout des Prozesses zugreifen kannst.

    Naja, das (ursprüngliche Vorhaben) klingt für mich nach ziemlicher hack-Arbeit, da müsstest du wahrscheinlich bei den Codern die hinter der Implementierung deiner C-Standard-Lib stehen (glibc, BSD libc, ...?) nachfragen.

    Ich würd mal schätzen wenn du auf etwas unixoidem unterwegs bist ist comp.unix.programmer ein guter Anlaufpunkt, auch wenn du dort wahrscheinlich nur weiterführende Links und/oder hilfreiche Belehrungen ala "Lass es" bekommst (ehehe). Aber wie ich das mitbekommen hab laufen dort Leute mit Ahnung rum.
     
  6. mythos

    mythos Mitglied

    Dabei seit:
    20.09.2005
    Beiträge:
    27
    Zustimmungen:
    0
    Ich glaub, du stellst dir das falsch vor. Ich versuche ein bisschen besser zu beschreiben, woran ich eigentlich arbeite. (Die Antwort passt zwar nicht umbedingt auf deine Fragen, aber ...)

    Immer, wenn ich Testtool schreibe, meine ich sowas wie einen selbstgeschriebenen C-Compiler, der zwar keinen Code produziert, aber einiges an Analyse-Arbeit leistet. Nun moechte ich Support zur Analyse/zum Aufzeichnen von stdout, stderr, etc. schaffen und in den Compiler integrieren. Die einfachste Methode Aenderungen am Compiler vorzunehmen ist es Aenderungen _nicht_ am Compiler selbst vorzunehmen, sondern in der libc oder in den Testdrivern. Testdriver ist eine main() Funktion, die bestehenden (zu testenden) Programmcode exemplarisch aufruft.

    Fuer's erste wollte ich versuchen nur stdout aufzuzeichnen. Wenn jemand auf stderr oder in ein File schreibt, ist mir das egal. Am Code under Test soll nichts veraendert werden. Ich kann also nicht hergehen und alle printfs im Programm gegen sprintfs ersetzten. Die Idee war, sich vor die Standardlib reinzuhacken, in pseudo-code:

    // mein printf(.)
    int printf(.) {
    //speichere alles was auf printf rausgeht in einem riesigen buffer, der sich selbst dynamisch vergroessert
    // ruf das echte printf auf und tu su als waere nicht's gewesen
    return printf(.)
    }

    Und das fuer alle Funktionen die auf stdout schreiben koennen. Bei fprintf ist das ein bisschen komplizierter, etc etc.

    Die pipe-Idee war zwar im Prinzip recht cool. Mein Compiler kann das aber nicht richtig verarbeiten.

    Im Grunde funktioniert es auch Funktionen von der Standardlib zu ersetzen oder neu zu schreiben, aber im Moment implementiere ich Zweit-Version der Funktion mit prefix "my_".

    Funktioniert es auch, wenn beide Funktionen gleich heissen. Im besten Fall sollte das Interface nach auszen gleich bleiben. (Andernfalls kann ich automatisiert zwar alle printf(.) gegen my_printf(.) mit einem Preprocessing-Schritt ersetzen lassen; lieber waer's mir, wenn ich das einsparen koennte.) Wie bring ich (zum Beispiel dem gcc) bei, dass ich eine eigene Versionen von printf habe und gleichzeitig das echte printf verwenden moechte? Kann ich aus Libs nur teilweise inkludieren? (z.B.: Ich hab' mein eigenes standalone printf geschrieben. Wie bring ich dem gcc bei, dass ich den Prototypen von printf nicht brauche, aber den Rest von stdio.h schon? Wie bring ich gcc bei, dass ich nur printf von der standardlib nicht linken will?)
     
  7. #6 faxe410, 27.05.2010
    faxe410

    faxe410 Grünschnabel

    Dabei seit:
    27.05.2010
    Beiträge:
    5
    Zustimmungen:
    0
    Ist dein Applikation dynamisch gelinkt? Wenn ja kannst du den dynamic linker dazu zwingen eine ander Bibliothek vor der libc zu laden. Diese andere Bibliothek kann dann eine eigene Implementierung der printf Funktion beinhalten. Der Vorteil ist dass du weder in den eigentlichen Code, noch in den Kompelierprozess eingreifen musst.

    Beispiel:
    main.c:

    #include <stdio.h>
    #include <stdlib.h>

    int main(int argc, char *argv[])
    {
    printf("Hallo World!\n");
    printf("Hallo Du");

    return 0;
    }


    mylib.c:

    #include <stdio.h>

    int printf(const char *format, ...)
    {
    fprintf(stdout, "Aufruf meiner privaten printf Funktion!\n");
    return 0;
    }

    int puts(const char *s)
    {
    fprintf(stdout, "Aufruf meiner privaten puts Funktion!\n");
    return 1;
    }


    Übersetzen:
    gcc -Wall -o main main.c
    gcc -shared -Wall -o libmy.so mylib.c

    Beim Aufruf wird der dynamic linker nun dazu gezwungen die Library libmy.so vor der libc zu laden:

    # LD_LIBRARY_PATH=/home/rainer/unixboard/preload LD_PRELOAD="libmy.so" ./main
    Aufruf meiner privaten puts Funktion!
    Aufruf meiner privaten printf Funktion!
    #


    Anscheinend wird irgendwo beim Übersetzten von main.c erkannt, dass beim ersten Aufruf von printf ein Newline verwendet wird und daher wird intern die puts Funktion verwendet.

    Hoffe das hilft!

    LG,
    Faxe
     
  8. Anzeige

    Vielleicht findest du HIER Antworten.
    Registrieren bzw. einloggen, um diese und auch andere Anzeigen zu deaktivieren
Thema:

printf modifizieren und stdout capturn

Die Seite wird geladen...

printf modifizieren und stdout capturn - Ähnliche Themen

  1. "printf" ausgabe hinten anhängen

    "printf" ausgabe hinten anhängen: hallo, ich hänge bei meinem script immer an der gleichen Stelle... ipPrefix="192.168.38"; # erster Teil der IP-Adresse...
  2. printf Formatierung: echo schreibt bei Ausgabeumleitung auf File nichts. Wieso?

    printf Formatierung: echo schreibt bei Ausgabeumleitung auf File nichts. Wieso?: #!/bin/sh ZAHL="372" FARBE="gelb" printf "%s%06d%s" "Bearbeitungsnummer 888" $ZAHL ", Farbe: $FARBE" echo printf "%s%06d%s" "Bearbeitungsnummer...
  3. find -printf und sekundendarstellung

    find -printf und sekundendarstellung: Hallo, nach einem Ditsributionsupdate meiner Linuxdistribution gab es Probleme mit einem Skript. Folgendes Beispiel: find *.rm -type f -printf...
  4. awk: printf schlägt fehl, wenn Steuerzeichen im Argument

    awk: printf schlägt fehl, wenn Steuerzeichen im Argument: Hallo zusammen, ich hatte bis eben (für mich) unerklärliche Probleme, wenn ich mit dem folgenden AWK eine Datei durchlaufen habe, die ein...
  5. echo/printf Formatierung (Ausrichtung)

    echo/printf Formatierung (Ausrichtung): Hallo, kann man echo bzw. printf dazu bringen, Text rechtsbündig auszugeben? Oder muss man da awk bemühen? Wie macht man das?