diff options
author | Karel Klic <kklic@redhat.com> | 2009-11-30 15:10:42 +0100 |
---|---|---|
committer | Karel Klic <kklic@redhat.com> | 2009-11-30 15:10:42 +0100 |
commit | 3b97c373a8d6bce4fa8b8ae5f014f83dab39d09a (patch) | |
tree | cd20a309e35ae77cabf4bf45d90724ecc5d3830a /src/Backtrace | |
parent | 0bde5aff06915f888b1a6c6a1309b7ee56058c8a (diff) | |
download | abrt-3b97c373a8d6bce4fa8b8ae5f014f83dab39d09a.tar.gz abrt-3b97c373a8d6bce4fa8b8ae5f014f83dab39d09a.tar.xz abrt-3b97c373a8d6bce4fa8b8ae5f014f83dab39d09a.zip |
abrt-backtrace handle more corner cases, silently exit on python backtraces
Diffstat (limited to 'src/Backtrace')
-rwxr-xr-x | src/Backtrace/abrt-bz-downloader | 20 | ||||
-rw-r--r-- | src/Backtrace/main.c | 71 | ||||
-rw-r--r-- | src/Backtrace/parser.y | 84 |
3 files changed, 124 insertions, 51 deletions
diff --git a/src/Backtrace/abrt-bz-downloader b/src/Backtrace/abrt-bz-downloader index 7d86a674..ef29acfb 100755 --- a/src/Backtrace/abrt-bz-downloader +++ b/src/Backtrace/abrt-bz-downloader @@ -48,25 +48,7 @@ for buginfo in buginfos: continue # Skip bugs with broken or Python backtraces - broken_backtrace_bugs = [ 517116, 518511, 518516, 518708, 518923, - 518923, 518981, 519134, 519367, 520287, - 521582, 521923, 521953, 522047, 522048, - 522973, 522975, 522976, 522982, 523194, - 523198, 523226, 523230, 523257, 523272, - 523274, 523295, 523301, 523328, 523656, - 523676, 523685, 523686, 523687, 523688, - 523793, 523798, 523847, 523863, - 523866, 523890, 523994, 524088, 524128, - 524294, 524322, - 524341, 524700, 524715, 525094, 525674, - 538546, 538547, 538554, 538560, 538650, - 538668, - 538822, 538823, 538824, - 539229, 539234, 539249, 539251, 539270, - 539294, 539302, - 539309, 539311, 539326, 539335, - 539342, 539374, 539378, - 539422, 539440, 539452 ] + broken_backtrace_bugs = [ 528529, 532264, 533475 ] if buginfo.bug_id in broken_backtrace_bugs: continue diff --git a/src/Backtrace/main.c b/src/Backtrace/main.c index 315b6efb..0761d31a 100644 --- a/src/Backtrace/main.c +++ b/src/Backtrace/main.c @@ -114,6 +114,8 @@ parse_opt (int key, char *arg, struct argp_state *state) /* Our argp parser. */ static struct argp argp = { options, parse_opt, args_doc, doc }; +#define PYTHON_BACKTRACE_ID1 "\n\nTraceback (most recent call last):\n" +#define PYTHON_BACKTRACE_ID2 "\n\nLocal variables in innermost frame:\n" int main(int argc, char **argv) { @@ -161,6 +163,15 @@ int main(int argc, char **argv) bttext[size] = '\0'; fclose(fp); + /* Detect Python backtraces. If it is a Python backtrace, + * silently exit for now. + */ + if (strstr(bttext, PYTHON_BACKTRACE_ID1) != NULL + && strstr(bttext, PYTHON_BACKTRACE_ID2) != NULL) + { + exit(0); + } + /* Print independent backtrace and exit. */ if (arguments.independent) { @@ -173,17 +184,65 @@ int main(int argc, char **argv) /* Skip the backtrace header information. */ char *btnoheader_a = strstr(bttext, "\nThread "); - char *btnoheader_b = strstr(bttext, "#"); + char *btnoheader_b = strstr(bttext, "\n#"); char *btnoheader = bttext; - if (btnoheader < btnoheader_a) - btnoheader = btnoheader_a + 1; - if (btnoheader < btnoheader_b) - btnoheader = btnoheader_b; + if (btnoheader_a) + { + if (btnoheader_b && btnoheader_b < btnoheader_a) + btnoheader = btnoheader_b + 1; + else + btnoheader = btnoheader_a + 1; + } + else if (btnoheader_b) + btnoheader = btnoheader_b + 1; + + /* Bug fixing hack for broken backtraces. + * Sometimes the empty line is missing before new Thread section. + * This is against rules, but a bug (now fixed) in Linux kernel caused + * this. + */ + char *thread_fixer = btnoheader + 1; + while ((thread_fixer = strstr(thread_fixer, "\nThread")) != NULL) + { + if (thread_fixer[-1] != '\n') + thread_fixer[-1] = '\n'; + + ++thread_fixer; + } + + /* Bug fixing hack for GDB. + * Sometimes there is a newline in the local variable section. + * This is caused by some GDB hooks. + * Example: rhbz#538440 + * #1 0x0000000000420939 in sync_deletions (mse=0x0, mfld=0x1b85020) + * at mail-stub-exchange.c:1119 + * status = <value optimized out> + * iter = 0x1af38d0 + * known_messages = 0x1b5c460Traceback (most recent call last): + * File "/usr/share/glib-2.0/gdb/glib.py", line 98, in next + * if long (node["key_hash"]) >= 2: + * RuntimeError: Cannot access memory at address 0x11 + * + * __PRETTY_FUNCTION__ = "sync_deletions" + * #2 0x0000000000423e6b in refresh_folder (stub=0x1b77f10 [MailStubExchange], + * ... + */ + char *empty_line = btnoheader; + while ((empty_line = strstr(empty_line, "\n\n")) != NULL) + { + if (0 != strncmp(empty_line, "\n\nThread", strlen("\n\nThread"))) + { + /* Remove the empty line by converting the first newline to char. */ + empty_line[0] = 'X'; + } + ++empty_line; + } /* Cut the backtrace footer. * Footer: lines not starting with # or "Thread", and separated from * the backtrace body by a newline. */ + /* It is not necessary for now, because of the bug fixing hack for GDB. int i; for (i = size - 1; i > 0; --i) { @@ -198,7 +257,7 @@ int main(int argc, char **argv) bttext[i] = '\0'; break; } - } + }*/ /* Try to parse the backtrace. */ struct backtrace *backtrace; diff --git a/src/Backtrace/parser.y b/src/Backtrace/parser.y index ef510142..b10184d2 100644 --- a/src/Backtrace/parser.y +++ b/src/Backtrace/parser.y @@ -78,11 +78,14 @@ void yyerror(char const *s) file_name_char identifier_char identifier_char_no_templates + identifier_first_char identifier_braces_inside_char identifier_template_inside_char + variables_char + variables_char_no_framestart ws ws_nonl - '(' ')' '+' '-' '/' '.' '_' '~' '[' ']' '\r' + '(' ')' '+' '-' '/' '.' '_' '~' '[' ']' '\r' '?' '{' '}' 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 'u' 'v' 'w' 'x' 'y' 'z' 'A' 'B' 'C' 'D' 'E' 'F' 'G' 'H' 'I' 'J' 'K' 'L' 'M' 'N' @@ -124,7 +127,7 @@ backtrace : /* empty */ %dprec 1 } ; -threads : thread { $$ = $1; } +threads : thread | threads wsa thread { $$ = thread_add_sibling($1, $3); } ; @@ -226,6 +229,11 @@ frame_address_in_function : hexadecimal_number wss keyword_in wss function_call strbuf_free($1); $$ = $5; } + | hexadecimal_number wss keyword_in wss keyword_vtable wss keyword_for wss function_call + { + strbuf_free($1); + $$ = $9; + } ; file_location : file_name ':' digit_sequence @@ -237,17 +245,17 @@ file_location : file_name ':' digit_sequence ; variables : variables_line '\n' - | variables_line END - | variables_line wss_nonl '\n' - | variables_line wss_nonl END - | variables variables_line '\n' - | variables variables_line END - | variables variables_line wss_nonl '\n' - | variables variables_line wss_nonl END + | variables_line END + | variables_line wss_nonl '\n' + | variables_line wss_nonl END + | variables variables_line '\n' + | variables variables_line END + | variables variables_line wss_nonl '\n' + | variables variables_line wss_nonl END | variables wss_nonl variables_line '\n' - | variables wss_nonl variables_line END - | variables wss_nonl variables_line wss_nonl '\n' - | variables wss_nonl variables_line wss_nonl END + | variables wss_nonl variables_line END + | variables wss_nonl variables_line wss_nonl '\n' + | variables wss_nonl variables_line wss_nonl END ; variables_line : variables_char_no_framestart @@ -267,8 +275,11 @@ variables_char_no_framestart : digit | nondigit | '"' | '(' | ')' | '%' | '|' | '~' ; -function_call : function_name wss function_args - | return_type wss_nonl function_name wss function_args { $$ = $3; } +function_call : function_name wss function_args %dprec 3 + | return_type wss_nonl function_name wss function_args %dprec 2 + { $$ = $3; } + | function_name wss_nonl identifier_template wss function_args %dprec 1 + { $$ = $1; strbuf_free($3); } ; return_type : identifier { strbuf_free($1); } @@ -328,7 +339,7 @@ file_name_char : digit | nondigit | '-' | '+' | '/' | '.' * Example: something@GLIB_2_2 * CClass::operator= */ -identifier : nondigit %dprec 1 +identifier : identifier_first_char %dprec 1 { $$ = strbuf_new(); strbuf_append_char($$, $1); @@ -348,6 +359,11 @@ identifier : nondigit %dprec 1 } ; +identifier_first_char: nondigit + | '~' /* destructor */ + | '*' +; + identifier_char_no_templates : digit | nondigit | '@' | '.' | ':' | '=' | '!' | '*' | '+' | '-' | '[' | ']' | '~' | '&' | '/' | '%' | '^' @@ -357,7 +373,7 @@ identifier_char_no_templates : digit | nondigit | '@' | '.' | ':' | '=' /* Most of the special characters are required to support C++ * operator overloading. */ -identifier_char : identifier_char_no_templates | '>' | '<' +identifier_char : identifier_char_no_templates | '<'| '>' ; identifier_braces : '(' ')' @@ -376,20 +392,25 @@ identifier_braces : '(' ')' } ; -identifier_braces_inside : identifier_braces_inside_char +identifier_braces_inside : identifier_braces_inside_char %dprec 1 { $$ = strbuf_new(); strbuf_append_char($$, $1); } - | identifier_braces_inside identifier_braces_inside_char + | identifier_braces_inside identifier_braces_inside_char %dprec 1 { $$ = strbuf_append_char($1, $2); } - | identifier_braces_inside '(' identifier_braces_inside ')' + | identifier_braces_inside '(' identifier_braces_inside ')' %dprec 1 { $$ = strbuf_append_char($1, $2); $$ = strbuf_append_str($1, $3->buf); strbuf_free($3); $$ = strbuf_append_char($1, $4); } + | identifier_braces_inside identifier_template %dprec 2 + { + $$ = strbuf_append_str($1, $2->buf); + strbuf_free($2); + } ; identifier_braces_inside_char : identifier_char | ws_nonl @@ -411,14 +432,19 @@ identifier_template_inside : identifier_template_inside_char strbuf_append_char($$, $1); } | identifier_template_inside identifier_template_inside_char - { $$ = strbuf_append_char($1, $2); } + { $$ = strbuf_append_char($1, $2); } | identifier_template_inside '<' identifier_template_inside '>' - { - $$ = strbuf_append_char($1, $2); - $$ = strbuf_append_str($1, $3->buf); - strbuf_free($3); - $$ = strbuf_append_char($1, $4); - } + { + $$ = strbuf_append_char($1, $2); + $$ = strbuf_append_str($1, $3->buf); + strbuf_free($3); + $$ = strbuf_append_char($1, $4); + } + | identifier_template_inside identifier_braces + { + $$ = strbuf_append_str($1, $2->buf); + strbuf_free($2); + } ; identifier_template_inside_char : identifier_char_no_templates | ws_nonl @@ -495,6 +521,12 @@ keyword_in : 'i' 'n' keyword_at : 'a' 't' ; +keyword_for : 'f' 'o' 'r' +; + +keyword_vtable : 'v' 't' 'a' 'b' 'l' 'e' +; + keyword_from : 'f' 'r' 'o' 'm' ; |