C言語のSegmentation Fault。gdbで原因調査しても終わっているところがわかりません。


C言語でsyntaxhighlight.cを簡単な構文強調(シンタックスハイライト)をして表示したいと考えているのですが、下のコードを実行するとterminal1のようになってしまいます。一応色々調べてみて、gdbで原因を突き止めようとしましたが、できませんでした。

誰かこの原因を教えてください、お願いします。

  * syntaxhighlight.cは合計396行、警告やエラーはありません。
  * gccのバージョンは10.2.1
  * コンパイルコマンドは gcc -o "syntaxhighlight" "syntaxhighlight.c" -Wall -g -O0 です

syntaxhighlight.c

[code]

    #include <stdio.h>
    #include <string.h>
    #include <ctype.h>
    #include <stdlib.h>
    
    #define ERROR -1
    
    int c;
    char * keywords [] = {
      "int", "double", "short", "char"
    };
    
    enum {
      UNDEFINED, ALPHABET, NUMBER, SIGN, HASH, STRING, CALC_SIGN, SPACE
    };
    
    int include (const char * src, const char ** str)
    {
      while (str != NULL) {
        if (strcmp(src, *str) == 0)
          return 1; // 見つかった
        else
          str++;
      }
    
      return 0; // 見つからなかった
    }
    
    int alpha (const char * src)
    {
      if (include(src, (const char **)keywords) == 1) {
        printf("\x1b[1m\x1b[38;5;38m%s", src);
      } else {
        printf("\x1b[0m%s", src);
      }
    
      return strlen(src);
    }
    
    int number (const char * src)
    {
      printf("\x1b[94m%s", src);
    
      return strlen(src);
    }
    
    int string (const char * src)
    {
      printf("\x1b[33m%s", src);
    
      return strlen(src);
    }
    
    int hash (const char * src)
    {
      printf("\x1b[38;5;250m%s", src);
    
      return strlen(src);
    }
    
    int calc_sign (const char * src)
    {
      printf("\x1b[38;5;252m%s", src);
    
      return strlen(src);
    }
    
    int sign (const char * src)
    {
      printf("\x1b[38;5;248m%s", src);
    
      return strlen(src);
    }
    
    int space (const char * src)
    {
      while (*src) {
        if (*src == '\t') {
          printf("\x1b[0m%s", "  ");
          src++;
          continue;
        }
        printf("\x1b[0m%c", *src);
        src++
      }
    
      return strlen(src);
    }
    
    int type (int c)
    {
      if (isalpha(c)) {
        return ALPHABET;
      } else if ((c - '0') <= 9 && (c - '0') >= 0) {
        return NUMBER;
      } else if (strchr("&()^~|[]{},;:?", c) != 0) {
        return SIGN;
      } else if (c == "#") {
        return HASH;
      } else if (c == '"' || c == '\'') {
        return STRING;
      } else if (strchr("!%%-=+*/", c) != 0) {
        return CALC_SIGN; 
      } else {
        return SPACE;
      }
      return ERROR;
    }
    
    int main (void)
    {
      FILE * fp = fopen("syntaxhighlight.c", "r");
      char code[50] = "";
      int codenow = 0;
      int before = UNDEFINED;
    
      while ((c = fgetc(fp)) != EOF) {
        switch (type(c)) {
          case ALPHABET:
            if (before == ALPHABET) {
              code[codenow++] = c;
            } else {
              if (before != UNDEFINED) {
                switch (before) {
                  case NUMBER:
                  number(code);
                    break;
                  case STRING:
                    string(code);
                    break;
                  case HASH:
                    hash();
                    break;
                  case CALC_SIGN:
                    calc_sign();
                    break;
                  case SIGN:
                    sign();
                    break;
                  case SPACE:
                    space();
                    break;
                  default:
                    fprintf(stderr, "\n\x1b[91mERROR: %s: %d: before内の値が期待されるものでなかったため、プログラムを強制終了しました。\n\n", __func__, __LINE__);
                  exit(ERROR);
                }
                code[0] = '\0';
                codenow = 0;
                code[codenow] = c;
                before = ALPHABET;
              } else {
                before = ALPHABET;
                code[codenow++] = c;
              }
            }
            break;
          case CALC_SIGN:
            if (before == CALC_SIGN) {
              code[codenow++] = c;
            } else {
              if (before != UNDEFINED) {
                switch (before) {
                  case NUMBER:
                    number(code);
                    break;
                  case STRING:
                    string(code);
                    break;
                  case HASH:
                    hash();
                    break;
                  case ALPHABET:
                    alpha();
                    break;
                  case SIGN:
                    sign();
                    break;
                  case SPACE:
                    space();
                    break;
                  default:
                    fprintf(stderr, "\n\x1b[91mERROR: %s: %d: before内の値が期待されるものでなかったため、プログラムを強制終了しました。\n\n", __func__, __LINE__);
                    exit(ERROR);
                }
                code[0] = '\0';
                codenow = 0;
                code[codenow] = c; // 追加
                before = CALC_SIGN;
              } else {
                before = CALC_SIGN;
                code[codenow++] = c;
              }
            }
            break;
          case HASH:
            if (before == HASH) {
              code[codenow++] = c;
            } else {
              if (before != UNDEFINED) {
                switch (before) {
                  case NUMBER:
                    number(code);
                    break;
                  case STRING:
                    string(code);
                    break;
                  case ALPHABET:
                    alpha();
                    break;
                  case CALC_SIGN:
                    calc_sign();
                    break;
                  case SIGN:
                    sign();
                    break;
                  case SPACE:
                    space();
                    break;
                  default:
                    fprintf(stderr, "\n\x1b[91mERROR: %s: %d: before内の値が期待されるものでなかったため、プログラムを強制終了しました。\n\n", __func__, __LINE__);
                    exit(ERROR);
                }
                code[0] = '\0';
                codenow = 0;
                code[codenow] = c;
                before = ALPHABET;
              } else {
                before = ALPHABET;
                code[codenow++] = c;
              }
            }
            break;
          case NUMBER:
            if (before == NUMBER) {
              code[codenow++] = c;
            } else {
              if (before != UNDEFINED) {
                switch (before) {
                  case ALPHABET:
                    alpha(code);
                    break;
                  case STRING:
                    string(code);
                    break;
                  case HASH:
                    hash();
                    break;
                  case CALC_SIGN:
                    calc_sign();
                    break;
                  case SIGN:
                    sign();
                    break;
                  case SPACE:
                    space();
                    break;
                  default:
                    fprintf(stderr, "\n\x1b[91mERROR: %s: %d: before内の値が期待されるものでなかったため、プログラムを強制終了しました。\n\n", __func__, __LINE__);
                    exit(ERROR);
                }
                code[0] = '\0';
                codenow = 0;
                code[codenow] = c;
                before = NUMBER;
              } else {
                before = NUMBER;
                code[codenow++] = c;
              }
            }
            break;
          case SIGN:
            if (before == SIGN) {
              code[codenow++] = c;
            } else {
              if (before != UNDEFINED) {
                switch (before) {
                  case NUMBER:
                    number(code);
                    break;
                  case STRING:
                    string(code);
                    break;
                  case HASH:
                    hash();
                    break;
                  case CALC_SIGN:
                    calc_sign();
                    break;
                  case ALPHABET:
                    alpha();
                    break;
                  case SPACE:
                    space();
                    break;
                  default:
                    fprintf(stderr, "\n\x1b[91mERROR: %s: %d: before内の値が期待されるものでなかったため、プログラムを強制終了しました。\n\n", __func__, __LINE__);
                    exit(ERROR);
                }
                code[0] = '\0';
                codenow = 0;
                code[codenow] = c;
                before = SIGN;
              } else {
                before = SIGN;
                code[codenow++] = c;
              }
            }
            break;
          case SPACE:
            if (before == SPACE) {
              code[codenow++] = c;
            } else {
              if (before != UNDEFINED) {
                switch (before) {
                  case NUMBER:
                    number(code);
                    break;
                  case STRING:
                    string(code);
                    break;
                  case HASH:
                    hash();
                    break;
                  case CALC_SIGN:
                    calc_sign();
                    break;
                  case SIGN:
                    sign();
                    break;
                  case ALPHABET:
                    alpha();
                    break;
                  default:
                    fprintf(stderr, "\n\x1b[91mERROR: %s: %d: before内の値が期待されるものでなかったため、プログラムを強制終了しました。\n\n", __func__, __LINE__);
                    exit(ERROR);
                }
                code[0] = '\0';
                codenow = 0;
                code[codenow] = c;
                before = SPACE;
              } else {
                before = SPACE;
                code[codenow++] = c;
              }
            }
            break;
          case STRING:
            if (before == STRING) {
              code[codenow++] = c;
            } else {
              if (before != UNDEFINED) {
                switch (before) {
                  case NUMBER:
                    number(code);
                    break;
                  case ALPHABET:
                    alpha(code);
                    break;
                  case HASH:
                    hash();
                    break;
                  case CALC_SIGN:
                    calc_sign();
                    break;
                  case SIGN:
                    sign();
                    break;
                  case SPACE:
                    space();
                    break;
                  default:
                    fprintf(stderr, "\n\x1b[91mERROR: %s: %d: before内の値が期待されるものでなかったため、プログラムを強制終了しました。\n\n", __func__, __LINE__);
                    exit(ERROR);
                }
                code[0] = '\0';
                codenow = 0;
                code[codenow] = c;
                before = STRING;
              } else {
                before = STRING;
                code[codenow++] = c;
              }
            }
            break;
          default:
            fprintf(stderr, "\n\x1b[91mERROR: 問題が発生したため、プログラムを強制終了しました。\n");
            exit(ERROR);
        } // switch end
      } // while end
    
      fclose(fp);
    
      puts("end");
    
      return 0;
    } // main end
    
[/code]

terminal1

[code]

    pi@raspberrypi:~/C_Language $ ./systaxhighlight
    Segmentation fault
    pi@raspberrypi:~/C_Language $ gdb ./syntaxhighlight core
    GNU gdb (Raspbian 10.1-1.7) 10.1.90.20210103-git
    Copyright (C) 2021 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law
    Type "show copying" and "show warranty" for details.
    This GDB was configured as "arm-linux-gnueabihf".
    Type "show configuration" for configuration details.
    For bug reporting instuctions, please see:
    <https://www.gnu.org/software/gdb/bugs/>.
    Find the GDB manual and other documentation resources online at:
        <http://www.gnu.org/software/gdb/documentation/>.
    
    For help, type "help".
    Type "apropos word" to search for commands related to "word"...
    Reading symbols from ./syntaxhighlight...
    
    warning: exec file is newer than core file.
    [New LWP 1025]
    Core was generated by `./syntaxhighlight'
    Program terminated with signal SIGSEGV, Segmentation fault.
    #0 0x00010488 in ?? ()
    (gdb) bt
    #0 0x00010488 in ?? ()
    #1 0xb6ddf608 in ?? ()
    Backtrace stopped: previous frame identical to this frame (corrupt stack?)
    (gdb)
    
[/code]




実行ファイルにシンボルが含まれていないようなので、まずは `gcc -g -Wall -o syntaxhighlight
syntaxhighlight.c` でコンパイルが成功してから実行してみましょう。

