summaryrefslogtreecommitdiffstats
path: root/src/Backtrace
diff options
context:
space:
mode:
authorKarel Klic <kklic@redhat.com>2009-11-30 15:10:42 +0100
committerKarel Klic <kklic@redhat.com>2009-11-30 15:10:42 +0100
commit3b97c373a8d6bce4fa8b8ae5f014f83dab39d09a (patch)
treecd20a309e35ae77cabf4bf45d90724ecc5d3830a /src/Backtrace
parent0bde5aff06915f888b1a6c6a1309b7ee56058c8a (diff)
downloadabrt-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-xsrc/Backtrace/abrt-bz-downloader20
-rw-r--r--src/Backtrace/main.c71
-rw-r--r--src/Backtrace/parser.y84
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'
;