Fossil

Check-in [48c06b0a13]
Login

Check-in [48c06b0a13]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:More information in the log file for signal handlers. Include the phase of operation as part of the log message.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 48c06b0a134b4b3188eac410b50a8173386cbcb9b390381c663be1ad23282d4c
User & Date: drh 2021-08-08 18:20:36.358
Context
2021-08-09
01:11
Markdown enhancement (after [forum:/forumpost/938896d37da30394|forum post 938896d37da30394] and follow-ups) in which <html>...</html> that is preceded and followed by blank lines disables all markdown processing and just returns raw HTML text. The <html> and its end-tag are removed. Removal of "dangerous" HTML is handled in a later pass, so the results should still be safe. ... (check-in: 1e919d601f user: drh tags: trunk)
2021-08-08
18:20
More information in the log file for signal handlers. Include the phase of operation as part of the log message. ... (check-in: 48c06b0a13 user: drh tags: trunk)
2021-08-07
17:28
Improved error message upon timeout. Combine redundant implementations of the function that finds user and kernel CPU usage. ... (check-in: 6c3d370496 user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/backoffice.c.
482
483
484
485
486
487
488

489
490
491
492
493
494
495
  sqlite3_uint64 tmNow;
  sqlite3_uint64 idSelf;
  int lastWarning = 0;
  int warningDelay = 30;
  static int once = 0;

  if( sqlite3_db_readonly(g.db, 0) ) return;

  backoffice_error_check_one(&once);
  idSelf = backofficeProcessId();
  while(1){
    tmNow = time(0);
    db_begin_write();
    backofficeReadLease(&x);
    if( x.tmNext>=tmNow







>







482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
  sqlite3_uint64 tmNow;
  sqlite3_uint64 idSelf;
  int lastWarning = 0;
  int warningDelay = 30;
  static int once = 0;

  if( sqlite3_db_readonly(g.db, 0) ) return;
  g.zPhase = "backoffice";
  backoffice_error_check_one(&once);
  idSelf = backofficeProcessId();
  while(1){
    tmNow = time(0);
    db_begin_write();
    backofficeReadLease(&x);
    if( x.tmNext>=tmNow
Changes to src/main.c.
141
142
143
144
145
146
147

148
149
150
151
152
153
154
};
#endif

struct Global {
  int argc; char **argv;  /* Command-line arguments to the program */
  char *nameOfExe;        /* Full path of executable. */
  const char *zErrlog;    /* Log errors to this file, if not NULL */

  int isConst;            /* True if the output is unchanging & cacheable */
  const char *zVfsName;   /* The VFS to use for database connections */
  sqlite3 *db;            /* The connection to the databases */
  sqlite3 *dbConfig;      /* Separate connection for global_config table */
  char *zAuxSchema;       /* Main repository aux-schema */
  int dbIgnoreErrors;     /* Ignore database errors if true */
  char *zConfigDbName;    /* Path of the config database. NULL if not open */







>







141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
};
#endif

struct Global {
  int argc; char **argv;  /* Command-line arguments to the program */
  char *nameOfExe;        /* Full path of executable. */
  const char *zErrlog;    /* Log errors to this file, if not NULL */
  const char *zPhase;     /* Phase of operation, for use by the error log */
  int isConst;            /* True if the output is unchanging & cacheable */
  const char *zVfsName;   /* The VFS to use for database connections */
  sqlite3 *db;            /* The connection to the databases */
  sqlite3 *dbConfig;      /* Separate connection for global_config table */
  char *zAuxSchema;       /* Main repository aux-schema */
  int dbIgnoreErrors;     /* Ignore database errors if true */
  char *zConfigDbName;    /* Path of the config database. NULL if not open */
671
672
673
674
675
676
677

678
679
680
681
682
683
684
** being called by separate invocations of fossil_main().
*/
int fossil_main(int argc, char **argv){
  const char *zCmdName = "unknown";
  const CmdOrPage *pCmd = 0;
  int rc;


#if !defined(_WIN32_WCE)
  if( fossil_getenv("FOSSIL_BREAK") ){
    if( isatty(0) && isatty(2) ){
      fprintf(stderr,
          "attach debugger to process %d and press any key to continue.\n",
          GETPID());
      fgetc(stdin);







>







672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
** being called by separate invocations of fossil_main().
*/
int fossil_main(int argc, char **argv){
  const char *zCmdName = "unknown";
  const CmdOrPage *pCmd = 0;
  int rc;

  g.zPhase = "init";
#if !defined(_WIN32_WCE)
  if( fossil_getenv("FOSSIL_BREAK") ){
    if( isatty(0) && isatty(2) ){
      fprintf(stderr,
          "attach debugger to process %d and press any key to continue.\n",
          GETPID());
      fgetc(stdin);
955
956
957
958
959
960
961

962

963
964
965
966
967
968
969
    rc = Th_CommandHook(pCmd->zName, pCmd->eCmdFlags);
  }else{
    rc = TH_OK;
  }
  if( rc==TH_OK || rc==TH_RETURN || rc==TH_CONTINUE ){
    if( rc==TH_OK || rc==TH_RETURN ){
#endif

      pCmd->xFunc();

#ifdef FOSSIL_ENABLE_TH1_HOOKS
    }
    if( !g.isHTTP && !g.fNoThHook && (rc==TH_OK || rc==TH_CONTINUE) ){
      Th_CommandNotify(pCmd->zName, pCmd->eCmdFlags);
    }
  }
#endif







>

>







957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
    rc = Th_CommandHook(pCmd->zName, pCmd->eCmdFlags);
  }else{
    rc = TH_OK;
  }
  if( rc==TH_OK || rc==TH_RETURN || rc==TH_CONTINUE ){
    if( rc==TH_OK || rc==TH_RETURN ){
#endif
      g.zPhase = pCmd->zName;
      pCmd->xFunc();
      g.zPhase = "shutdown";
#ifdef FOSSIL_ENABLE_TH1_HOOKS
    }
    if( !g.isHTTP && !g.fNoThHook && (rc==TH_OK || rc==TH_CONTINUE) ){
      Th_CommandNotify(pCmd->zName, pCmd->eCmdFlags);
    }
  }
#endif
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552

1553
1554
1555
1556
1557
1558
1559
  size_t size;
  char **strings;
  size_t i;
  Blob out;
  size = backtrace(array, sizeof(array)/sizeof(array[0]));
  strings = backtrace_symbols(array, size);
  blob_init(&out, 0, 0);
  blob_appendf(&out, "Segfault");
  for(i=0; i<size; i++){
    blob_appendf(&out, "\n(%d) %s", i, strings[i]);
  }
  fossil_panic("%s", blob_str(&out));
#else
  fossil_panic("Segfault");
#endif
  exit(1);
}

/*
** Called if a server gets a SIGPIPE.  This often happens when a client
** webbrowser opens a connection but never sends the HTTP request
*/
void sigpipe_handler(int x){
#ifndef _WIN32
  if( g.fAnyTrace ){
    fprintf(stderr,"/***** sigpipe received by subprocess %d ****\n", getpid());
  }
#endif

  db_panic_close();
  exit(1);
}

/*
** Return true if it is appropriate to redirect requests to HTTPS.
**







|





|














>







1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
  size_t size;
  char **strings;
  size_t i;
  Blob out;
  size = backtrace(array, sizeof(array)/sizeof(array[0]));
  strings = backtrace_symbols(array, size);
  blob_init(&out, 0, 0);
  blob_appendf(&out, "Segfault during %s", g.zPhase);
  for(i=0; i<size; i++){
    blob_appendf(&out, "\n(%d) %s", i, strings[i]);
  }
  fossil_panic("%s", blob_str(&out));
#else
  fossil_panic("Segfault during %s", g.zPhase);
#endif
  exit(1);
}

/*
** Called if a server gets a SIGPIPE.  This often happens when a client
** webbrowser opens a connection but never sends the HTTP request
*/
void sigpipe_handler(int x){
#ifndef _WIN32
  if( g.fAnyTrace ){
    fprintf(stderr,"/***** sigpipe received by subprocess %d ****\n", getpid());
  }
#endif
  g.zPhase = "sigpipe shutdown";
  db_panic_close();
  exit(1);
}

/*
** Return true if it is appropriate to redirect requests to HTTPS.
**
1618
1619
1620
1621
1622
1623
1624

1625
1626
1627
1628
1629
1630
1631
){
  const char *zPathInfo = PD("PATH_INFO", "");
  char *zPath = NULL;
  int i;
  const CmdOrPage *pCmd = 0;
  const char *zBase = g.zRepositoryName;


#if !defined(_WIN32)
  signal(SIGSEGV, sigsegv_handler);
#endif

  /* Handle universal query parameters */
  if( PB("utc") ){
    g.fTimeFormat = 1;







>







1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
){
  const char *zPathInfo = PD("PATH_INFO", "");
  char *zPath = NULL;
  int i;
  const CmdOrPage *pCmd = 0;
  const char *zBase = g.zRepositoryName;

  g.zPhase = "process_one_web_page";
#if !defined(_WIN32)
  signal(SIGSEGV, sigsegv_handler);
#endif

  /* Handle universal query parameters */
  if( PB("utc") ){
    g.fTimeFormat = 1;
2020
2021
2022
2023
2024
2025
2026

2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039

2040
2041
2042
2043
2044
2045
2046
        rc = Th_WebpageHook(pCmd->zName+1, pCmd->eCmdFlags);
      }else{
        rc = TH_OK;
      }
      if( rc==TH_OK || rc==TH_RETURN || rc==TH_CONTINUE ){
        if( rc==TH_OK || rc==TH_RETURN ){
#endif

          pCmd->xFunc();
#ifdef FOSSIL_ENABLE_TH1_HOOKS
        }
        if( !g.fNoThHook && (rc==TH_OK || rc==TH_CONTINUE) ){
          Th_WebpageNotify(pCmd->zName+1, pCmd->eCmdFlags);
        }
      }
    }
#endif
  }

  /* Return the result.
  */

  cgi_reply();
}

/* If the CGI program contains one or more lines of the form
**
**    redirect:  repository-filename  http://hostname/path/%s
**







>













>







2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
        rc = Th_WebpageHook(pCmd->zName+1, pCmd->eCmdFlags);
      }else{
        rc = TH_OK;
      }
      if( rc==TH_OK || rc==TH_RETURN || rc==TH_CONTINUE ){
        if( rc==TH_OK || rc==TH_RETURN ){
#endif
          g.zPhase = pCmd->zName;
          pCmd->xFunc();
#ifdef FOSSIL_ENABLE_TH1_HOOKS
        }
        if( !g.fNoThHook && (rc==TH_OK || rc==TH_CONTINUE) ){
          Th_WebpageNotify(pCmd->zName+1, pCmd->eCmdFlags);
        }
      }
    }
#endif
  }

  /* Return the result.
  */
  g.zPhase = "web-page reply";
  cgi_reply();
}

/* If the CGI program contains one or more lines of the form
**
**    redirect:  repository-filename  http://hostname/path/%s
**
2783
2784
2785
2786
2787
2788
2789
2790

2791
2792
2793
2794
2795
2796
2797
2798
** is one) and exiting.
*/
#ifndef _WIN32
static int nAlarmSeconds = 0;
static void sigalrm_handler(int x){
  sqlite3_uint64 tmUser = 0, tmKernel = 0;
  fossil_cpu_times(&tmUser, &tmKernel);
  fossil_panic("Timeout after %d seconds - user %,llu µs, sys %,llu µs",

               nAlarmSeconds, tmUser, tmKernel);
}
#endif

/*
** Arrange to timeout using SIGALRM after N seconds.  Or if N==0, cancel
** any pending timeout.
**







|
>
|







2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
** is one) and exiting.
*/
#ifndef _WIN32
static int nAlarmSeconds = 0;
static void sigalrm_handler(int x){
  sqlite3_uint64 tmUser = 0, tmKernel = 0;
  fossil_cpu_times(&tmUser, &tmKernel);
  fossil_panic("Timeout after %d seconds during %s"
               " - user %,llu µs, sys %,llu µs",
               nAlarmSeconds, g.zPhase, tmUser, tmKernel);
}
#endif

/*
** Arrange to timeout using SIGALRM after N seconds.  Or if N==0, cancel
** any pending timeout.
**
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
  style_submenu_element("Error Log","%R/errorlog");
  if( iCase<1 || iCase>4 ){
    @ <p>Generate a message to the <a href="%R/errorlog">error log</a>
    @ by clicking on one of the following cases:
  }else{
    @ <p>This is the test page for case=%d(iCase).  All possible cases:
  }
  for(i=1; i<=7; i++){
    @ <a href='./test-warning?case=%d(i)'>[%d(i)]</a>
  }
  @ </p>
  @ <p><ol>
  @ <li value='1'> Call fossil_warning()
  if( iCase==1 ){
    fossil_warning("Test warning message from /test-warning");







|







3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
  style_submenu_element("Error Log","%R/errorlog");
  if( iCase<1 || iCase>4 ){
    @ <p>Generate a message to the <a href="%R/errorlog">error log</a>
    @ by clicking on one of the following cases:
  }else{
    @ <p>This is the test page for case=%d(iCase).  All possible cases:
  }
  for(i=1; i<=8; i++){
    @ <a href='./test-warning?case=%d(i)'>[%d(i)]</a>
  }
  @ </p>
  @ <p><ol>
  @ <li value='1'> Call fossil_warning()
  if( iCase==1 ){
    fossil_warning("Test warning message from /test-warning");
3275
3276
3277
3278
3279
3280
3281






3282
3283
3284
3285
3286
  if( iCase==6 ){
    webpage_assert( 5==7 );
  }
  @ <li value='7'> call webpage_error()"
  if( iCase==7 ){
    cgi_reset_content();
    webpage_error("Case 7 from /test-warning");






  }
  @ </ol>
  @ <p>End of test</p>
  style_finish_page();
}







>
>
>
>
>
>





3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
  if( iCase==6 ){
    webpage_assert( 5==7 );
  }
  @ <li value='7'> call webpage_error()"
  if( iCase==7 ){
    cgi_reset_content();
    webpage_error("Case 7 from /test-warning");
  }
  @ <li value='8'> simulated timeout"
  if( iCase==8 ){
    fossil_set_timeout(1);
    cgi_reset_content();
    sqlite3_sleep(1100);
  }
  @ </ol>
  @ <p>End of test</p>
  style_finish_page();
}