mikrocontroller.net

Forum: PC-Programmierung Linux C zweiten Terminal für debugging


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: Geronimo S. (guitronimo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich bin neu hier und brauche mal etwas Hilfe, vielleicht findet sich ein 
command line Ninja, der mir auf die Sprünge helfen mag, für die 
Suchmaschinen habe ich wohl nicht den passenden Begriff gefunden...

In einem echt dicken C Projekt will ich den Debug Output vom 
eigentlichen Terminal trennen.

Da das aber ohne Shared Memory nicht so ohne weiteres zu gehen scheint, 
dachte ich an sowas wie pthread!?

Wie würde ich A: in einem pthread einen Terminal öffnen? "system()" 
fällt da glaube ich flach, da ich ja quasi darin ein Programm executen 
muss?

Wie würde ich B: Den Output in einen zweiten Terminal umleiten können?

Oder gibts vielleicht noch eine geschicktere Variante? ncurses, stdio zu 
pid umleiten?! Echt keinen plan gerade...

Vielen Dank vorab!

Schicken Abend,

Joe

Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gibst du deine Debug-Informationen in die Konsole aus 
(/var/log/messages), oder in das Terminal, in dem das Programm gestartet 
wurde?

Bei ersterem:
tail -f /var/log/messages | grep <Programmname>

Bei zweitem hast du ja nur deine Ausgaben oder starten mit
<Programm> > /meine/logdatei.log

Oder gleich im Programm in eine Datei ausgeben.

Autor: Geronimo S. (guitronimo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tom schrieb:
> Gibst du deine Debug-Informationen in die Konsole aus
> (/var/log/messages), oder in das Terminal, in dem das Programm gestartet
> wurde?
>
> Bei ersterem:
> tail -f /var/log/messages | grep <Programmname>
>
> Bei zweitem hast du ja nur deine Ausgaben oder starten mit
> <Programm> > /meine/logdatei.log
>
> Oder gleich im Programm in eine Datei ausgeben.

Verzeihung, war vielleicht inkomplett formuliert.

Ich gebe den Output ins terminal aus. Files zu schreiben und stetig neu 
zu laden ist mir zu lästig. Das ist ein runtime debugging.

Ich will quasi aus C heraus ein zweites Termial starten und den Debug 
output dorthin umleiten.

Beste grüße

Autor: Sam H. (samhain)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
/der/pfad/zu/deinem/programm|grep was-auch-immer

Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Geronimo S. schrieb:
> Files zu schreiben und stetig neu
> zu laden ist mir zu lästig

Muss man nicht, siehe tail -f

Du kannst aber auch direkt nach stdout schreiben, dann kommen die 
Ausgaben in der Shell, in der das Programm gestartet wurde, verstehe 
nicht warum du noch eine extra Terminal brauchst

Autor: Geronimo S. (guitronimo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tom schrieb:
> verstehe
> nicht warum du noch eine extra Terminal brauchst

Weil der debugging output, der noch unabdingbar ist, den output des 
terminals unlesbar macht und umgekehrt.

Ich benötige ein zweites fenster, in dem live der debug mitläuft und ich 
will vermeiden, den output in eine datei zu schreiben.


lg

Autor: samhain (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> verstehe nicht warum du noch eine extra Terminal brauchst
der TO kommt von Windows und ist erst kurz auf linux unterwegs.

Autor: B. S. (bestucki)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Geronimo S. schrieb:
> Ich benötige ein zweites fenster, in dem live der debug mitläuft und ich
> will vermeiden, den output in eine datei zu schreiben.

Grundsätzlich steht einem Programm nur eine Konsole zu. Da du nicht in 
eine Datei schreiben willst, schlage ich mal ncurses vor. Du hast zwar 
immernoch nur eine Konsole, kannst diese jedoch in unabhängige Bereiche 
unterteilen. Die Einarbeitungszeit ist relativ überschaubar.

Autor: Sam H. (samhain)
Datum:

Bewertung
2 lesenswert
nicht lesenswert
Da kommt mir eine lustige Idee:

du macht ein mal das da:

mkfifo /tmp/stdout
mkfifo /tmp/stderr
xterm -title /tmp/stdout -e tail -f /tmp/stdout &
xterm -title /tmp/stderr -e tail -f /tmp/stderr &

und dann schickst du den output von deinem Programm zu den 2 fifos:

/pfad/zu/deinem/programm >/tmp/stdout 2>/tmp/stderr

Debug-Output schreibst du in deinem Programm nach stderr, normalen 
output nach stdout. Und du hast dann sogar 3 terminals ...

Autor: NichtWichtig (Gast)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
named pipes

Autor: foobar (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hatten wir das nicht neulich schon mal?!?
#include <stdio.h>
#include <unistd.h>

int
main(int argc, char **argv)
{
    FILE *debugfd;
    int i;

    debugfd = popen("xterm 9<&0 -e cat /dev/fd/9", "w");
    setlinebuf(debugfd);
    for (i = 0; i < 3; ++i)
    {
        fprintf(debugfd, "Hello World! %d\n", i);
        sleep(3);
    }
    return 0;
}

Funktioniert mit xterm aber nicht mit einigen modernen Nachbauten (die 
schließen gerne alle Filedeskriptoren).

Autor: samhain (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Aller GNOME und GTK-3 basierende Krempel funktioniert nicht korrekt - u 
nd hat WONTFIXes in den Bugtrackern :(

Autor: macgyver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
selber machen (ein file öffnen und dann über der descriptor schreiben 
zusammen mit 'tail -f' und evtl 'grep') scheint zu kompliziert zu sein. 
könnte man auch schön in ein eigenes (wiederverwendbares) Modul packen. 
aber wurscht

wie wärs mit was fertigem wie z.b. log4c?
https://sourceforge.net/projects/log4c/

ist definitiv komplexer in der Anwendung als der Selbstbau, aber mir 
solls egal sein.

Autor: Rolf M. (rmagnus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Geronimo S. schrieb:
>> Oder gleich im Programm in eine Datei ausgeben.
>
> Verzeihung, war vielleicht inkomplett formuliert.
>
> Ich gebe den Output ins terminal aus. Files zu schreiben und stetig neu
> zu laden ist mir zu lästig.

Was ist daran lästig? Du musst es einmal am Anfang öffnen, und dann 
schreibst du da rein, wie auf stdout auch. Und wenn du es live in einem 
anderen Terminal sehen willst, zeigst du es mit tail -f an. Als Bonus 
hast du das logfile, das du dir auch nachträglich mal anschauen kannst, 
wenn du es doch mal brauchen solltest.

> Ich will quasi aus C heraus ein zweites Termial starten und den Debug
> output dorthin umleiten.

Das erfordert dann aber, dass du eine graphische Oberfläche mit allem 
drum und dran hast. Per ssh kannst du das nicht nutzen. Wäre mir zu 
unflexibel.
Du könntest in eine Pipe schreiben. Dann kannst du einfach von Hand ein 
zweites Terminal aufmachen und dort mit cat den Inhalt der Pipe 
ausgeben.

Autor: Sam H. (samhain)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Windows User :)

Autor: Joerg W. (joergwolfram)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich nutze für solche Zwecke meist SDL(2), da hält sich auch der Aufwand 
in Grenzen.

Jörg

Autor: Geronimo S. (guitronimo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten morgen,

erstmal vielen Dank für eure Antworten.

Also erstmal ist mir garnichts zu kompliziert. Ich dachte nur, dass es 
eventuell einen Weg gibt, der mir nicht bekannt ist, so quasi auf kurzem 
dienstweg.. tail -f ist als temporäre Lösung okay, nur nicht was ich 
möchte.
Ich werde es vermutlich über einen shared memory lösen müssen und 
einfach mit zwei oder mehr terminals arbeiten. Hat den vorteil, dass ich 
dem hauptprozess dann auch steuern kann.

Um kurz das projekt zu erklären, damit die Frage "warum" klar ist.
Ich schreibe einen softcore einer 80186 CPU mit Pin emulation um 
hardware da drum herum zu simulieren und reverse zu engineeren. Zum 
Beispiel den 82586 Netzwerkchip, 8259 interrupt controller, externe BIU 
mit arbitrierung, etliche GALS,  Hard SHM mit MMU, Z85C Serial chip und 
etliche mehr, insgesamt gibt es ~15 devices, nur auf diesem board.

Da die Roms, die ich darin laufen lasse, das "quasi" hauptprogramm 
abspielen und ausgeben, will ich den output der anderen Bausteine extern 
ausgeben. Extern heisst in diesem fall aber auch nur simuliert über 
terminals, vorerst.

Die Serial ports zum Beispiel müssen in beide richtungen funktionieren, 
dafür nutze ich bereits einen pthread mit ncurses um die tastatur 
abzufangen. Funktioniert auch, zerstört nur den output im terminal. Da 
ich den content der Roms nicht editieren will/kann, sind curses als 
quasi display split nicht so einfach nutzbar, geht auch aber an der 
sache vorbei.

Grafik erspare ich mir, erstens hab ich keine lust und zeit, den 
debugger zu debuggen, zweitens muss später im projekt der grafikchip und 
Ramdac für VGA emuliert werden. Da ich mich aber noch für keine 
grafiklib entschieden habe, will ich jetzt nicht einfach irgendwas 
nutzen.


Lg, ich berichte wie ich es gemacht habe.

Joe

Autor: Bernd K. (prof7bit)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sam H. schrieb:
> Windows User :)

Nein, er hat pthread gesagt, also kein Windows.

--

Also ich würde es gleich richtig machen und alles mit syslog loggen:
https://linux.die.net/man/3/syslog

Dann fügt sich das nahtlos ins Gesamtsystem ein, man kann es an 
zentraler Stelle filtern, umleiten, ignorieren, etc., mit den selben 
Werkzeugen wie für alle anderen Logs, und es macht keine Extra-Zicken 
die dem Sysadmin zusätzliche Forschungsarbeit bereiten bis er 
herausgefunden hat wie er Dein Logging in den Griff bekommt und welche 
Extrawürste er dafür braten muß.

Autor: Geronimo S. (guitronimo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Joerg W. schrieb:
> Ich nutze für solche Zwecke meist SDL(2), da hält sich auch der Aufwand
> in Grenzen.
>
> Jörg

Hallo Jörg,

SDL hab ich im moment noch als Favoriten für die aufwendigeren Ausgaben.
Mir ist da die Lernkurve gerade nur zu steil, da noch viel arbeit am 
projekt ansich ist.

Lg

Autor: Joerg W. (joergwolfram)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du könntest ja z.B. das Fenster nicht 640x480 sondern 640x720 groß 
machen und unterhalb des VGA-Bereiches die interessanten Variablen 
ausgeben. Die ersten 480 Zeilen bleiben halt erst mal ungenutzt.

Das wäre meiner Meinung nach sogar noch übersichtlicher als die Werte 
nacheinander in ein Log oder Fenster zu schreiben.

Jörg

Autor: DPA (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
foobar schrieb:
> Hatten wir das nicht neulich schon mal?!?

Ich fragte mal was ähnliches: (die verlinkte logfunktionen wurde seither 
etwas erweitert und einige zeilen verschoben)
Beitrag "Leeres Terminal für Ausgabe aus anderem Prozess öffnen (linux)"

Einfach mal die manpage von getenv, dprintf/vdprintf, etc. anschauen, 
dann ist das recht simpel ne kleine debug funktion zu schreiben.

(Für logging verwende ich sonst auch gerne syslog, aber wenn ich 
tausende kleine debug meldungen für mich selbst einbaue, brauchen die 
nicht immer die logs zu fluten).

Autor: foobar (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>> Hatten wir das nicht neulich schon mal?!?
>
> Ich fragte mal was ähnliches: [...]

Ah genau, als doch kein Déjà-vu ;-)

Btw,
    debugfd = popen("xterm -e cat /proc/$$/fd/0", "w");
sollte auch mit modernen Terminalemulatoren funktionieren.

Autor: Rolf M. (rmagnus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Geronimo S. schrieb:
> Also erstmal ist mir garnichts zu kompliziert. Ich dachte nur, dass es
> eventuell einen Weg gibt, der mir nicht bekannt ist, so quasi auf kurzem
> dienstweg..

Der wurde ja genannt.

> tail -f ist als temporäre Lösung okay, nur nicht was ich möchte.
> Ich werde es vermutlich über einen shared memory lösen müssen und
> einfach mit zwei oder mehr terminals arbeiten.

Warum keine Pipe? Zu einfach?

> Die Serial ports zum Beispiel müssen in beide richtungen funktionieren,
> dafür nutze ich bereits einen pthread mit ncurses um die tastatur
> abzufangen. Funktioniert auch, zerstört nur den output im terminal.

Irgendwie hab ich bei deinen Beschreibungen immer Schwierigkeiten, die 
Zusammenhänge zu verstehen. Warum brauchst du einen eigenen Thread und 
ncurses, um die Tastatur einzulesen, und was hat das mit bidirektionalen 
seriellen Schnittstellen zu tun, oder mit einem kaputten 
Terminal-Output?

> Da ich den content der Roms nicht editieren will/kann, sind curses als
> quasi display split nicht so einfach nutzbar,

Auch das ist mir nicht klar. Warum solltest du was am ROM ändern müssen, 
um die Ausgabe deines Emulators wo anders hinschreiben zu können?

Autor: foobar (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
> Irgendwie hab ich bei deinen Beschreibungen immer Schwierigkeiten,
> die Zusammenhänge zu verstehen.

In der Tat - mir scheint, er selbst hat das gleiche Problem ;-)

Autor: Geronimo S. (guitronimo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Rolf M. schrieb:
> Geronimo S. schrieb:
>> Also erstmal ist mir garnichts zu kompliziert. Ich dachte nur, dass es
>> eventuell einen Weg gibt, der mir nicht bekannt ist, so quasi auf kurzem
>> dienstweg..
>
> Der wurde ja genannt.
>
>> tail -f ist als temporäre Lösung okay, nur nicht was ich möchte.
>> Ich werde es vermutlich über einen shared memory lösen müssen und
>> einfach mit zwei oder mehr terminals arbeiten.
>
> Warum keine Pipe? Zu einfach?
>
>> Die Serial ports zum Beispiel müssen in beide richtungen funktionieren,
>> dafür nutze ich bereits einen pthread mit ncurses um die tastatur
>> abzufangen. Funktioniert auch, zerstört nur den output im terminal.
>
> Irgendwie hab ich bei deinen Beschreibungen immer Schwierigkeiten, die
> Zusammenhänge zu verstehen. Warum brauchst du einen eigenen Thread und
> ncurses, um die Tastatur einzulesen, und was hat das mit bidirektionalen
> seriellen Schnittstellen zu tun, oder mit einem kaputten
> Terminal-Output?
>
>> Da ich den content der Roms nicht editieren will/kann, sind curses als
>> quasi display split nicht so einfach nutzbar,
>
> Auch das ist mir nicht klar. Warum solltest du was am ROM ändern müssen,
> um die Ausgabe deines Emulators wo anders hinschreiben zu können?

Das Gerät gibt insgesamt auf 6 Serial Ports Daten ein und aus.
Serial 1. Anwender Programm
Serial 2. Debugger
Serial 3-6 sind 4 Bi-Direktionale RS485 Lanes (Eine Pipeline unter 
diversen Karten).

Ich emuliere das aber alles nur inkl. CPU und allen anderen genannten 
Komponenten. Es hängen also keine Physikalischen Terminals an einem 
Serial Port sondern virtuelle Terminals.

Der Debugger allein packt 400 MB in 6 Sekunden aus, deswegen ist der 
Output von Terminal 1 unlesbar. Zugegeben, der ist meine Programmierung 
(Runtime Disassembly) mit Tastatureingabe (Stepping, Start, Stop, etc).

Ich hatte mit ncurses versucht 2 Serials zu verbinden, der pthread dient 
dazu, keine I/s beim printf des debuggers zu verlieren, da bot sich dann 
auch gleich das abfangen der Tastatur an.

Meine Frage stellte ich, weil ich den Output, der an port xxxx:xxxx geht 
(im emulator) nicht im selben terminal schreiben will, der auch port 
xxxx:xxxy darstellt.

Wie auch immer. Ich bin wie gesagt jetzt schon dabei einen shared memory 
dafür einzurichten und von verschiedenen Prozessen lesen zu lassen, hab 
da aber gerade ein paar synchronisierungs Probleme. Ich berichte wie ich 
es gelöst habe, wenn ich es zum laufen habe.

lg

Autor: Geronimo S. (guitronimo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
foobar schrieb:
>> Irgendwie hab ich bei deinen Beschreibungen immer
> Schwierigkeiten,
>> die Zusammenhänge zu verstehen.
>
> In der Tat - mir scheint, er selbst hat das gleiche Problem ;-)

Ah, ja jetzt wo ihr beide der Meinung seid... Ich denke mal drüber nach, 
wenn ich Zeit dafür habe.

lg

Autor: Bernd K. (prof7bit)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Geronimo S. schrieb:
> Wie auch immer. Ich bin wie gesagt jetzt schon dabei einen shared memory
> dafür einzurichten und von verschiedenen Prozessen lesen zu lassen, hab
> da aber gerade ein paar synchronisierungs Probleme.

Ja, das wird sicherlich einfacher zu sein als ne zweite Konsole mit
tail -f

: Bearbeitet durch User
Autor: DPA (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Geronimo S. schrieb:
> Ich emuliere das aber alles nur inkl. CPU und allen anderen genannten
> Komponenten. Es hängen also keine Physikalischen Terminals an einem
> Serial Port sondern virtuelle Terminals.

Füge doch doch einfach ne config datei, environment variablen oder 
argumente oder sowas hinzu, wo man die ttys angeben kann, und wenn keins 
angegeben ist, öffne ein Pseudoterminal. Bei pseudoterminals kannst do 
das andere ende dann später mit minicom/picocom/etc. öffnen. Shared 
memory usw sind hier echt überflüssig.

https://linux.die.net/man/4/ptmx
http://man7.org/linux/man-pages/man3/openpty.3.html

Autor: Eric B. (beric)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Geronimo S. schrieb:
> Da die Roms, die ich darin laufen lasse, das "quasi" hauptprogramm
> abspielen und ausgeben, will ich den output der anderen Bausteine extern
> ausgeben.

Seit wann spielen ROMs was ab und geben aus?

: Bearbeitet durch User
Autor: Geronimo S. (guitronimo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eric B. schrieb:
> Geronimo S. schrieb:
>> Da die Roms, die ich darin laufen lasse, das "quasi" hauptprogramm
>> abspielen und ausgeben, will ich den output der anderen Bausteine extern
>> ausgeben.
>
> Seit wann spielen ROMs was ab und geben aus?

Milchmädchen Frage...

Hätte ich UMCS geschrieben hätte es auch keiner kapiert.

Lg

Autor: Widersprecher (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenns dir darum geht, die Ein-/Ausgaben über die seriellen 
Schnittstellen zu loggen, dann schau dir mal socat an. Das kann auch 
PTYs und mit -v/-x etc. kann es auch schön dumpen, was über die PTY 
geht. Incl. Timestamp.

Autor: Sam H. (samhain)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
... und hätte der TO anstell hier herumzuhängen sich um die Beantwortung 
der Frage selber gekümmert, hätte er schon eine funktionierende Lösung 
...

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.