Workaround ndk-stack.exe 64-bit mingw build
Regex generated by x86_64-w64-mingw32 compiler erroneously matches
frame line with #[0-9]+ in "stack:" section even when the line has no
word "pc", "eip", or "ip" in it, eg.
stack:
I/DEBUG ( 1151): #00 5f09db68 401f01c4 /system/lib/libc.so
Workaround by double-checking the line does contain pc, and ensure it
is a word, not part of filename or something
Change-Id: I247fca80cc20ab16fb4c46eb39b82b91c6f90317
diff --git a/sources/host-tools/ndk-stack/ndk-stack-parser.c b/sources/host-tools/ndk-stack/ndk-stack-parser.c
index 9753244..9ac6934 100755
--- a/sources/host-tools/ndk-stack/ndk-stack-parser.c
+++ b/sources/host-tools/ndk-stack/ndk-stack-parser.c
@@ -124,6 +124,14 @@
*/
static const char* get_next_token(const char* str, char* token, size_t size);
+/* Return pointer to first word "pc", "eip", or "ip" in string "frame"
+ * param:
+ * frame - a line from dump
+ * Return:
+ * The first occurrence of "pc", "eip", or "ip"
+ */
+static const char* find_pc(const char *frame);
+
NdkCrashParser*
CreateNdkCrashParser(FILE* out_handle, const char* sym_root)
{
@@ -220,12 +228,22 @@
// Let it fall through to the EXPECTS_FRAME, in case the dump doesn't
// contain signal fingerprint.
case EXPECTS_FRAME:
- if (MatchRegex(line, &parser->re_frame_header, &match)) {
- parser->state = EXPECTS_FRAME;
- return ParseFrame(parser, line + match.rm_so);
- } else {
+ if (!MatchRegex(line, &parser->re_frame_header, &match))
return !found;
- }
+ // Regex generated by x86_64-w64-mingw32 compiler erroneously match
+ // frame line with #[0-9]+ in "stack:" section even when the line has
+ // no word "pc", "eip", or "ip" in it.
+ //
+ // stack:
+ // I/DEBUG ( 1151): #00 5f09db68 401f01c4 /system/lib/libc.so
+ //
+ // To workaround, let's double check if pc is found!
+ //
+ if (!(find_pc(line)))
+ return !found;
+
+ parser->state = EXPECTS_FRAME;
+ return ParseFrame(parser, line + match.rm_so);
default:
return 1;
@@ -275,6 +293,24 @@
}
}
+static const char *
+find_pc(const char *frame)
+{
+ const char *pcstrs[] = { "pc", "eip", "ip" };
+ int i;
+ for (i=0; i<sizeof(pcstrs)/sizeof(pcstrs[0]); i++) {
+ const char *p = strstr(frame, pcstrs[i]);
+ // check it's a word, not part of filename or something
+ if (p && p!=frame) {
+ char l = p[-1];
+ char r = p[strlen(pcstrs[i])];
+ if ((l==' ' || l=='\t') && (r==' ' || r=='\t'))
+ return p;
+ }
+ }
+ return NULL;
+}
+
int
ParseFrame(NdkCrashParser* parser, const char* frame)
{
@@ -297,17 +333,10 @@
fprintf(parser->out_handle, "Stack frame %s", frame);
// Advance to the instruction pointer token.
- wrk = strstr(frame, "pc");
- if (wrk == NULL) {
- wrk = strstr(frame, "eip");
- if (wrk == NULL) {
- wrk = strstr(frame, "ip");
- if (wrk == NULL) {
- fprintf(parser->out_handle,
- "Parser is unable to locate instruction pointer token.\n");
- return -1;
- }
- }
+ if ((wrk=find_pc(frame)) == NULL) {
+ fprintf(parser->out_handle,
+ "Parser is unable to locate instruction pointer token.\n");
+ return -1;
}
// Next token after the instruction pointer token is its address.