Domanda

Proprio quando sono a fflush (stdout) e io ci spezzo in GDB, posso sapere cosa c'è in stdout prima che io in realtà stamparlo?

Come faccio a sapere cosa c'è in stdout in qualsiasi punto nel tempo?

È stato utile?

Soluzione

È quasi certamente possibile, ma probabilmente non dovrebbe. La norma richiede soltanto che FILE essere un tipo che è utile per la realizzazione di identificare un file aperto e qualunque stato è necessario per attuare la semantica delle varie funzioni che operano sui flussi.

Mi piacerebbe generalmente d'accordo con altri manifesti che fflush() è un modo affidabile per sapere ciò che effettivamente scritto al file.

Tuttavia, se avete perso le tracce di ciò che parti del codice potrebbe aver scritto in un flusso, allora può a volte essere utile per vedere il flusso in azione e lo prende cambiando.

In pratica, FILE è un typedef per una struct che viene dichiarato da l'implementazione nel file di intestazione stdio.h (spesso chiamato struct _iobuf). Anche se una tipica implementazione documenta solo leggermente i suoi membri, una tipica implementazione anche attrezzi putchar() e alcuni dei suoi amici come macro che si trovano anche in stdio.h. Questo, combinato con la probabile disponibilità di fonti per la libreria di runtime C di qualsiasi toolchain si rischia di utilizzare con gdb, si ottiene tutte le informazioni necessarie per peek sotto il cofano.

Lo stdio.h fornite in MinGW GCC 3.4.5 implementa FILE come segue:

typedef struct _iobuf
{
    char*   _ptr;
    int _cnt;
    char*   _base;
    int _flag;
    int _file;
    int _charbuf;
    int _bufsiz;
    char*   _tmpfname;
} FILE;

// oversimplify declaration of _iob[] here for clarity:
extern FILE _iob[FOPEN_MAX];    /* An array of FILE imported from DLL. */
//...
#define STDIN_FILENO    0
#define STDOUT_FILENO   1
#define STDERR_FILENO   2
#define stdin   (&_iob[STDIN_FILENO])
#define stdout  (&_iob[STDOUT_FILENO])
#define stderr  (&_iob[STDERR_FILENO])

e attrezzi putchar() come funzione inline approfittando di estensione GCC a C:

__CRT_INLINE int __cdecl __MINGW_NOTHROW putchar(int __c)
{
  return (--stdout->_cnt >= 0)
    ?  (int) (unsigned char) (*stdout->_ptr++ = (char)__c)
    :  _flsbuf (__c, stdout);}

Da questo si può dire che il fine del buffer è punta il _ptr membro, e dedurre che l'unica altra char * a struct _iobuf (_base) sta puntando l'inizio del buffer. Il _cnt membro è chiaramente il conteggio dei caratteri non utilizzati rimanenti nel buffer. La _flsbuf() funzione deve prendere il primo carattere che non si adatta e metterlo all'inizio del buffer dopo che ha scritto il contenuto del buffer corrente sul file e ripristinato il campo _cnt.

Quindi, se si guarda stdout->_base e BUFSIZ - stdout->_cnt si sarebbe, per questa implementazione, avere un display di quanto e cosa è nel buffer corrente.

Altri suggerimenti

Se si alloca un buffer da soli e passarlo a setvbuf , I supporti possono accedervi prima di un colore, dal momento che è tuo per cominciare.

Modifica Il tuo commento fatto il vostro intento più chiaro, ma ciò che si vuole non sarà facile:

  1. Imposta il tuo tampone come descritto sopra,
  2. Imposta un leggere watchpoint su stdout,
  3. Guarda il tuo programma di lenti a passo d'uomo.

Da allora in poi, gdb romperà ogni volta niente accessi stdout, e si può controllare il buffer per le modifiche, uscita strano, ecc.

Detto questo, che non è una soluzione ideale a tutti. Un approccio di gran lunga migliore sarebbe utilizzando una funzione di uscita di registrazione abilitata ovunque nel codice.

Credo che sia meglio stdout a filo, che in pratica significa che state vedendo il contenuto sullo schermo o in un file (se stdout viene reindirizzato).

l'uso "setbuf ()", e mantenere una maniglia per il buffer, che è possibile sbirciare. Purtroppo, non so fuori dalla parte superiore come trovare l'offset e la lunghezza dei dati unflushed.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top