Fossil SCM
Improved error logging following a segfault.
Commit
a8d220b9ff6deba678b979749b44485521b1aeb261f0ab9f0088c6d5c37c90c3
Parent
5542cd43b3fe305…
2 files changed
+1
+27
-2
M
auto.def
+1
| --- auto.def | ||
| +++ auto.def | ||
| @@ -483,10 +483,11 @@ | ||
| 483 | 483 | cc-check-function-in-lib ns_name_uncompress resolv |
| 484 | 484 | cc-check-functions utime |
| 485 | 485 | cc-check-functions usleep |
| 486 | 486 | cc-check-functions strchrnul |
| 487 | 487 | cc-check-functions pledge |
| 488 | +cc-check-functions backtrace | |
| 488 | 489 | |
| 489 | 490 | # Check for getloadavg(), and if it doesn't exist, define FOSSIL_OMIT_LOAD_AVERAGE |
| 490 | 491 | if {![cc-check-functions getloadavg]} { |
| 491 | 492 | define FOSSIL_OMIT_LOAD_AVERAGE 1 |
| 492 | 493 | msg-result "Load average support unavailable" |
| 493 | 494 |
| --- auto.def | |
| +++ auto.def | |
| @@ -483,10 +483,11 @@ | |
| 483 | cc-check-function-in-lib ns_name_uncompress resolv |
| 484 | cc-check-functions utime |
| 485 | cc-check-functions usleep |
| 486 | cc-check-functions strchrnul |
| 487 | cc-check-functions pledge |
| 488 | |
| 489 | # Check for getloadavg(), and if it doesn't exist, define FOSSIL_OMIT_LOAD_AVERAGE |
| 490 | if {![cc-check-functions getloadavg]} { |
| 491 | define FOSSIL_OMIT_LOAD_AVERAGE 1 |
| 492 | msg-result "Load average support unavailable" |
| 493 |
| --- auto.def | |
| +++ auto.def | |
| @@ -483,10 +483,11 @@ | |
| 483 | cc-check-function-in-lib ns_name_uncompress resolv |
| 484 | cc-check-functions utime |
| 485 | cc-check-functions usleep |
| 486 | cc-check-functions strchrnul |
| 487 | cc-check-functions pledge |
| 488 | cc-check-functions backtrace |
| 489 | |
| 490 | # Check for getloadavg(), and if it doesn't exist, define FOSSIL_OMIT_LOAD_AVERAGE |
| 491 | if {![cc-check-functions getloadavg]} { |
| 492 | define FOSSIL_OMIT_LOAD_AVERAGE 1 |
| 493 | msg-result "Load average support unavailable" |
| 494 |
+27
-2
| --- src/main.c | ||
| +++ src/main.c | ||
| @@ -48,10 +48,13 @@ | ||
| 48 | 48 | #endif |
| 49 | 49 | #ifdef FOSSIL_ENABLE_JSON |
| 50 | 50 | # include "cson_amalgamation.h" /* JSON API. */ |
| 51 | 51 | # include "json_detail.h" |
| 52 | 52 | #endif |
| 53 | +#ifdef HAVE_BACKTRACE | |
| 54 | +# include <execinfo.h> | |
| 55 | +#endif | |
| 53 | 56 | |
| 54 | 57 | /* |
| 55 | 58 | ** Maximum number of auxiliary parameters on reports |
| 56 | 59 | */ |
| 57 | 60 | #define MX_AUX 5 |
| @@ -1418,11 +1421,27 @@ | ||
| 1418 | 1421 | |
| 1419 | 1422 | /* |
| 1420 | 1423 | ** Called whenever a crash is encountered while processing a webpage. |
| 1421 | 1424 | */ |
| 1422 | 1425 | void sigsegv_handler(int x){ |
| 1423 | - fossil_errorlog("Segfault"); | |
| 1426 | +#if HAVE_BACKTRACE | |
| 1427 | + void *array[20]; | |
| 1428 | + size_t size; | |
| 1429 | + char **strings; | |
| 1430 | + size_t i; | |
| 1431 | + Blob out; | |
| 1432 | + size = backtrace(array, sizeof(array)/sizeof(array[0])); | |
| 1433 | + strings = backtrace_symbols(array, size); | |
| 1434 | + blob_init(&out, 0, 0); | |
| 1435 | + blob_appendf(&out, "Segfault"); | |
| 1436 | + for(i=0; i<size; i++){ | |
| 1437 | + blob_appendf(&out, "\n(%d) %s", i, strings[i]); | |
| 1438 | + } | |
| 1439 | + fossil_panic("%s", blob_str(&out)); | |
| 1440 | +#else | |
| 1441 | + fossil_panic("Segfault"); | |
| 1442 | +#endif | |
| 1424 | 1443 | exit(1); |
| 1425 | 1444 | } |
| 1426 | 1445 | |
| 1427 | 1446 | /* |
| 1428 | 1447 | ** Called if a server gets a SIGPIPE. This often happens when a client |
| @@ -2778,10 +2797,12 @@ | ||
| 2778 | 2797 | ** the administrator only. |
| 2779 | 2798 | ** |
| 2780 | 2799 | ** case=1 Issue a fossil_warning() while generating the page. |
| 2781 | 2800 | ** case=2 Extra db_begin_transaction() |
| 2782 | 2801 | ** case=3 Extra db_end_transaction() |
| 2802 | +** case=4 Error during SQL processing | |
| 2803 | +** case=5 Call the segfault handler | |
| 2783 | 2804 | */ |
| 2784 | 2805 | void test_warning_page(void){ |
| 2785 | 2806 | int iCase = atoi(PD("case","0")); |
| 2786 | 2807 | int i; |
| 2787 | 2808 | login_check_credentials(); |
| @@ -2795,11 +2816,11 @@ | ||
| 2795 | 2816 | @ <p>Generate a message to the <a href="%R/errorlog">error log</a> |
| 2796 | 2817 | @ by clicking on one of the following cases: |
| 2797 | 2818 | }else{ |
| 2798 | 2819 | @ <p>This is the test page for case=%d(iCase). All possible cases: |
| 2799 | 2820 | } |
| 2800 | - for(i=1; i<=4; i++){ | |
| 2821 | + for(i=1; i<=5; i++){ | |
| 2801 | 2822 | @ <a href='./test-warning?case=%d(i)'>[%d(i)]</a> |
| 2802 | 2823 | } |
| 2803 | 2824 | @ </p> |
| 2804 | 2825 | @ <p><ol> |
| 2805 | 2826 | @ <li value='1'> Call fossil_warning() |
| @@ -2819,10 +2840,14 @@ | ||
| 2819 | 2840 | Stmt q; |
| 2820 | 2841 | db_prepare(&q, "SELECT uuid FROM blob LIMIT 5"); |
| 2821 | 2842 | db_step(&q); |
| 2822 | 2843 | sqlite3_log(SQLITE_ERROR, "Test warning message during SQL"); |
| 2823 | 2844 | db_finalize(&q); |
| 2845 | + } | |
| 2846 | + @ <li value='5'> simulate segfault handling | |
| 2847 | + if( iCase==5 ){ | |
| 2848 | + sigsegv_handler(0); | |
| 2824 | 2849 | } |
| 2825 | 2850 | @ </ol> |
| 2826 | 2851 | @ <p>End of test</p> |
| 2827 | 2852 | style_footer(); |
| 2828 | 2853 | } |
| 2829 | 2854 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -48,10 +48,13 @@ | |
| 48 | #endif |
| 49 | #ifdef FOSSIL_ENABLE_JSON |
| 50 | # include "cson_amalgamation.h" /* JSON API. */ |
| 51 | # include "json_detail.h" |
| 52 | #endif |
| 53 | |
| 54 | /* |
| 55 | ** Maximum number of auxiliary parameters on reports |
| 56 | */ |
| 57 | #define MX_AUX 5 |
| @@ -1418,11 +1421,27 @@ | |
| 1418 | |
| 1419 | /* |
| 1420 | ** Called whenever a crash is encountered while processing a webpage. |
| 1421 | */ |
| 1422 | void sigsegv_handler(int x){ |
| 1423 | fossil_errorlog("Segfault"); |
| 1424 | exit(1); |
| 1425 | } |
| 1426 | |
| 1427 | /* |
| 1428 | ** Called if a server gets a SIGPIPE. This often happens when a client |
| @@ -2778,10 +2797,12 @@ | |
| 2778 | ** the administrator only. |
| 2779 | ** |
| 2780 | ** case=1 Issue a fossil_warning() while generating the page. |
| 2781 | ** case=2 Extra db_begin_transaction() |
| 2782 | ** case=3 Extra db_end_transaction() |
| 2783 | */ |
| 2784 | void test_warning_page(void){ |
| 2785 | int iCase = atoi(PD("case","0")); |
| 2786 | int i; |
| 2787 | login_check_credentials(); |
| @@ -2795,11 +2816,11 @@ | |
| 2795 | @ <p>Generate a message to the <a href="%R/errorlog">error log</a> |
| 2796 | @ by clicking on one of the following cases: |
| 2797 | }else{ |
| 2798 | @ <p>This is the test page for case=%d(iCase). All possible cases: |
| 2799 | } |
| 2800 | for(i=1; i<=4; i++){ |
| 2801 | @ <a href='./test-warning?case=%d(i)'>[%d(i)]</a> |
| 2802 | } |
| 2803 | @ </p> |
| 2804 | @ <p><ol> |
| 2805 | @ <li value='1'> Call fossil_warning() |
| @@ -2819,10 +2840,14 @@ | |
| 2819 | Stmt q; |
| 2820 | db_prepare(&q, "SELECT uuid FROM blob LIMIT 5"); |
| 2821 | db_step(&q); |
| 2822 | sqlite3_log(SQLITE_ERROR, "Test warning message during SQL"); |
| 2823 | db_finalize(&q); |
| 2824 | } |
| 2825 | @ </ol> |
| 2826 | @ <p>End of test</p> |
| 2827 | style_footer(); |
| 2828 | } |
| 2829 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -48,10 +48,13 @@ | |
| 48 | #endif |
| 49 | #ifdef FOSSIL_ENABLE_JSON |
| 50 | # include "cson_amalgamation.h" /* JSON API. */ |
| 51 | # include "json_detail.h" |
| 52 | #endif |
| 53 | #ifdef HAVE_BACKTRACE |
| 54 | # include <execinfo.h> |
| 55 | #endif |
| 56 | |
| 57 | /* |
| 58 | ** Maximum number of auxiliary parameters on reports |
| 59 | */ |
| 60 | #define MX_AUX 5 |
| @@ -1418,11 +1421,27 @@ | |
| 1421 | |
| 1422 | /* |
| 1423 | ** Called whenever a crash is encountered while processing a webpage. |
| 1424 | */ |
| 1425 | void sigsegv_handler(int x){ |
| 1426 | #if HAVE_BACKTRACE |
| 1427 | void *array[20]; |
| 1428 | size_t size; |
| 1429 | char **strings; |
| 1430 | size_t i; |
| 1431 | Blob out; |
| 1432 | size = backtrace(array, sizeof(array)/sizeof(array[0])); |
| 1433 | strings = backtrace_symbols(array, size); |
| 1434 | blob_init(&out, 0, 0); |
| 1435 | blob_appendf(&out, "Segfault"); |
| 1436 | for(i=0; i<size; i++){ |
| 1437 | blob_appendf(&out, "\n(%d) %s", i, strings[i]); |
| 1438 | } |
| 1439 | fossil_panic("%s", blob_str(&out)); |
| 1440 | #else |
| 1441 | fossil_panic("Segfault"); |
| 1442 | #endif |
| 1443 | exit(1); |
| 1444 | } |
| 1445 | |
| 1446 | /* |
| 1447 | ** Called if a server gets a SIGPIPE. This often happens when a client |
| @@ -2778,10 +2797,12 @@ | |
| 2797 | ** the administrator only. |
| 2798 | ** |
| 2799 | ** case=1 Issue a fossil_warning() while generating the page. |
| 2800 | ** case=2 Extra db_begin_transaction() |
| 2801 | ** case=3 Extra db_end_transaction() |
| 2802 | ** case=4 Error during SQL processing |
| 2803 | ** case=5 Call the segfault handler |
| 2804 | */ |
| 2805 | void test_warning_page(void){ |
| 2806 | int iCase = atoi(PD("case","0")); |
| 2807 | int i; |
| 2808 | login_check_credentials(); |
| @@ -2795,11 +2816,11 @@ | |
| 2816 | @ <p>Generate a message to the <a href="%R/errorlog">error log</a> |
| 2817 | @ by clicking on one of the following cases: |
| 2818 | }else{ |
| 2819 | @ <p>This is the test page for case=%d(iCase). All possible cases: |
| 2820 | } |
| 2821 | for(i=1; i<=5; i++){ |
| 2822 | @ <a href='./test-warning?case=%d(i)'>[%d(i)]</a> |
| 2823 | } |
| 2824 | @ </p> |
| 2825 | @ <p><ol> |
| 2826 | @ <li value='1'> Call fossil_warning() |
| @@ -2819,10 +2840,14 @@ | |
| 2840 | Stmt q; |
| 2841 | db_prepare(&q, "SELECT uuid FROM blob LIMIT 5"); |
| 2842 | db_step(&q); |
| 2843 | sqlite3_log(SQLITE_ERROR, "Test warning message during SQL"); |
| 2844 | db_finalize(&q); |
| 2845 | } |
| 2846 | @ <li value='5'> simulate segfault handling |
| 2847 | if( iCase==5 ){ |
| 2848 | sigsegv_handler(0); |
| 2849 | } |
| 2850 | @ </ol> |
| 2851 | @ <p>End of test</p> |
| 2852 | style_footer(); |
| 2853 | } |
| 2854 |