2017-11-30 10 views
0

シリアルポートからバッファに読み込みを行うCコードがあり、100バイトを読み込んだときに関数log_write()を使用してそれらを書き込みます。 一部のデータが欠落しているため、未定義の動作が発生していると思います。明らかにコードに間違いはありますか?シリアルポートからc - 配列インデックスの問題を読む

具体的には、以下の行に1を追加する必要がありますか?rdlentotal?以前の読み込みの最後の文字を上書きしていますか?

また、読み込まれた最後の文字の後にバッファを終了する必要がありますか?どうすればいい? Chuxから

rdlen = read(fd_joule, &ibuf[rdlentotal], sizeof(ibuf)); rdlentotal += rdlen; /*keep track of total bytes read*/

int rdlen=0, rdlentotal = 0; 
char ibuf[1024]; 

memset(&ibuf[0], 0, sizeof(ibuf)); /*clear the buffer*/ 

while (1) { 

    /*read from serial port*/ 
    rdlen = read(fd_joule, &ibuf[rdlentotal], sizeof(ibuf)); 
    rdlentotal += rdlen; /*keep track of total bytes read*/ 

    if (rdlentotal > 100) { /*when you have 200 bytes write the websocket*/ 
     log_write("%s", &ibuf); /*write to websocket*/ 
     memset(&ibuf[0], 0, sizeof(ibuf)); /*clear buffer*/ 
     rdlentotal = 0; /*rest byte counter */ 
     rdlen = 0; 
    } 

    if (rdlen < 0) { 
     fprintf(stderr, "rdlen les than 0\r\n"); 
    } 

} 

更新されたコードの提案:log_write()ため

static void *serial_logging_thread() { 

    ssize_t rdlen = 0, rdlentotal = 0; 
    char ibuf[1024 + 1]; 

    memset(&ibuf[0], 0, sizeof(ibuf)); /*clear the buffer*/ 

    while (1) { 

     /*read from serial port write to log file*/ 
     rdlen = read(fd_joule, &ibuf[rdlentotal], sizeof(ibuf) - 1 - rdlentotal); 
     rdlentotal += rdlen; 

     if (rdlentotal > 200) { /*when you have 200 bytes write to file and websocket*/ 

      ibuf[rdlentotal + 1] = '\0'; /*null terminate*/ 
      log_write("%s", &ibuf); /*write to websocket*/ 

      memset(&ibuf[0], 0, sizeof(ibuf)); /*clear buffer*/ 
      rdlentotal = 0; /*rest byte counter */ 
      rdlen = 0; 
     } 

     if (rdlen < 0) { 
      LOG("error reading serial port, rdlen less than 0\r\n"); 
     } 
    } 

} 

宣言。

int log_write(const char *fmt, ... /* arguments */){ 
+1

'読み出す(fd_joule、&IBUFは[rdlentotal]、はsizeof(IBUF));' - > '読み出す(fd_joule、&IBUFは[rdlentotal]、はsizeof(IBUF) - rdlentotal);' – chux

+1

教えます私たちにお願いします - バイトストリームにはNULが入っていますか?もしそうなら、あなたはすでに壊れている、下のchuxのヒント。 –

+0

samsung gathering:あなたの質問に回答のコピーを追加するのではなく、1)[私の質問に誰かが答えたときに何をすべきですか?](https://stackoverflow.com/help/someone-answers)2)ロールバック前のバージョンへのあなたの質問。 – chux

答えて

0

上記のコメントは正しいです。さらにコメントするには、メモリをibufで上書きしてスタックを破損させ、予測できない動作やクラッシュする可能性があります。

1

コードに間違いがありますか?

はい、以下を参照してください。

具体的には、以下の行に、1からrdlentotalを追加する必要がありますか?

は、前回のリードの最後の文字を上書きしますか?

...私が読まれる最後の文字の後にバッファをヌルすべきですか? bufストリングとして扱われる場合

はい。しかし、入力には'\0'バイトが含まれている可能性があるので、より堅牢なコードはbufを文字配列として扱い、bufとその長さをロギング関数に渡します。また、参照してください@Martin James

どうすればいいですか?

下記の#2を参照してください。

  1. バッファオーバーランの可能性:


    コードには、少なくとも次のような問題があります。

    // rdlen = read(fd_joule, &ibuf[rdlentotal], sizeof(ibuf)); 
    rdlen = read(fd_joule, &ibuf[rdlentotal], sizeof(ibuf) - rdlentotal); 
    
  2. log_write("%s", &ibuf);と仮定するとprintf()に似て、コードがではない可能性がある、ibufを印刷しようとしていると、それは確かにヌル文字終了ではありません。最初の読み取りがsizeof(ibuf)文字であれば何が起こるか考えてみてください。代わりに、スペースを確保してヌル文字を追加します。

    char ibuf[1024 + 1]; // add 1 here     - 1 below 
    ... 
    rdlen = read(fd_joule, &ibuf[rdlentotal], sizeof ibuf - 1 - rdlentotal); 
    ... 
    ibuf[rdlentotal + rdlen] = '\0'; // Code is certain to have memory for the \0 
    ... 
    log_write("%s", &ibuf); // The use of & here is likely not needed. 
    
  3. read()ssize_t、ないintを返します。そのタイプを使用してエラーをチェックrdlentotal += rdlen;

    ssize_t rdlen = read(... 
    if (rdlen == -1) { 
        LOG("error reading serial port, rdlen less than 0\r\n"); 
        continue; 
    } 
    rdlentotal += rdlen; 
    
  4. より堅牢前int

    // int rdlentotal = 0; 
    size_t rdlentotal = 0; 
    
  5. マイナーよりも配列の長さについてはsize_tを使用する:コメントがコードを反映するものではありません。

    // if (rdlentotal > 100) { /*when you have 200 bytes write the websocket*/ 
    if (rdlentotal > 100) { /*when you have more than 100 bytes write the websocket*/ 
    
関連する問題