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


von Geronimo S. (guitronimo)


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

von Tom (Gast)


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.

von Geronimo S. (guitronimo)


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

von Sam H. (samhain)


Lesenswert?

/der/pfad/zu/deinem/programm|grep was-auch-immer

von Tom (Gast)


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

von Geronimo S. (guitronimo)


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

von samhain (Gast)


Lesenswert?

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

von B. S. (bestucki)


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.

von Sam H. (samhain)


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 ...

von NichtWichtig (Gast)


Lesenswert?

named pipes

von foobar (Gast)


Lesenswert?

Hatten wir das nicht neulich schon mal?!?
1
#include <stdio.h>
2
#include <unistd.h>
3
4
int
5
main(int argc, char **argv)
6
{
7
    FILE *debugfd;
8
    int i;
9
10
    debugfd = popen("xterm 9<&0 -e cat /dev/fd/9", "w");
11
    setlinebuf(debugfd);
12
    for (i = 0; i < 3; ++i)
13
    {
14
        fprintf(debugfd, "Hello World! %d\n", i);
15
        sleep(3);
16
    }
17
    return 0;
18
}

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

von samhain (Gast)


Lesenswert?

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

von macgyver (Gast)


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.

von Rolf M. (rmagnus)


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.

von Sam H. (samhain)


Lesenswert?

Windows User :)

von Joerg W. (joergwolfram)


Lesenswert?

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

Jörg

von Geronimo S. (guitronimo)


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

von Bernd K. (prof7bit)


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ß.

von Geronimo S. (guitronimo)


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

von Joerg W. (joergwolfram)


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

von DPA (Gast)


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).

von foobar (Gast)


Lesenswert?

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

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

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

von Rolf M. (rmagnus)


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?

von foobar (Gast)


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 ;-)

von Geronimo S. (guitronimo)


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

von Geronimo S. (guitronimo)


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

von Bernd K. (prof7bit)


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
von DPA (Gast)


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

von Eric B. (beric)


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
von Geronimo S. (guitronimo)


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

von Widersprecher (Gast)


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.

von Sam H. (samhain)


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 
...

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.