Revision: 925 Author: teawater Date: Wed Feb 22 05:23:13 2012Log: Fix bug in gtp_frame_file_header that affect stack when src of conditon or action is bigger than 200.
http://code.google.com/p/kgtp/source/detail?r=925 Modified: /trunk/UPDATE /trunk/gtp.c ======================================= --- /trunk/UPDATE Mon Feb 20 23:17:57 2012 +++ /trunk/UPDATE Wed Feb 22 05:23:13 2012 @@ -16,6 +16,9 @@ * Remove GTP_VAR_NOT_GETV, GTP_VAR_NOT_SETV and GTP_VAR_NOT_TRACEV. +* Fix bug in gtp_frame_file_header that affect stack when src of conditon + or action is bigger than 200. + *** 20120131 * https://lkml.org/lkml/2012/1/31/215 ======================================= --- /trunk/gtp.c Mon Feb 20 23:17:57 2012 +++ /trunk/gtp.c Wed Feb 22 05:23:13 2012 @@ -205,6 +205,7 @@ #endif #define GTP_RW_MAX 16384 +#define GTP_RW_BUFP_MAX (GTP_RW_MAX - 4 - gtp_rw_size) #define FID_TYPE unsigned int #define FID_SIZE sizeof(FID_TYPE) @@ -957,8 +958,8 @@ { char *tmp; - if ((grs->real_size < grs->size + size) - || (is_end && grs->real_size != grs->size + size)) { + if (unlikely((grs->real_size < grs->size + size) + || (is_end && grs->real_size != grs->size + size))) { grs->real_size = grs->size + size; if (!is_end) grs->real_size += 100; @@ -994,6 +995,30 @@ return 0; } + +static inline void +gtp_realloc_reset(struct gtp_realloc_s *grs) +{ + grs->size = 0; +} + +static inline int +gtp_realloc_is_alloced(struct gtp_realloc_s *grs) +{ + return (grs->buf != NULL); +} + +static inline int +gtp_realloc_is_empty(struct gtp_realloc_s *grs) +{ + return (grs->size == 0); +} + +static inline void +gtp_realloc_sub_size(struct gtp_realloc_s *grs, size_t size) +{ + grs->size -= size; +} #ifdef CONFIG_X86 static ULONGEST @@ -2795,7 +2820,7 @@ uint8_t *ebuf = ae->u.exp.buf; int psize = GTP_PRINTF_MAX; char *pbuf = __get_cpu_var(gtp_printf); - ULONGEST *stack = __get_cpu_var(action_x_stack); + ULONGEST *stack = __get_cpu_var(action_x_stack); if (ae->u.exp.need_var_lock) spin_lock(>p_var_lock); @@ -3445,7 +3470,6 @@ } break; } - if (sp > STACK_MAX - 5) { printk(KERN_WARNING "gtp_action_x: stack " "overflow.\n"); @@ -6020,7 +6044,7 @@ else gtp_frame_head_find_num(old_num); #endif - strcpy(gtp_rw_bufp, "F-1"); + snprintf(gtp_rw_bufp, GTP_RW_BUFP_MAX, "F-1"); gtp_rw_bufp += 3; gtp_rw_size += 3; } else { @@ -6044,8 +6068,9 @@ tmp = ring_buffer_event_data(rbe); gtp_frame_current_tpe = *(ULONGEST *)(tmp + FID_SIZE); #endif - sprintf(gtp_rw_bufp, "F%xT%x", gtp_frame_current_num, - (unsigned int) gtp_frame_current_tpe); + snprintf(gtp_rw_bufp, GTP_RW_BUFP_MAX, "F%xT%x", + gtp_frame_current_num, + (unsigned int) gtp_frame_current_tpe); gtp_rw_size += strlen(gtp_rw_bufp); gtp_rw_bufp += strlen(gtp_rw_bufp); } @@ -6392,7 +6417,7 @@ } static int -gtp_get_status(struct gtp_entry *tpe, char *buf) +gtp_get_status(struct gtp_entry *tpe, char *buf, int bufmax) { int size = 0; int tfnum = 0; @@ -6404,39 +6429,41 @@ #if defined(GTP_FRAME_SIMPLE) || defined(GTP_FTRACE_RING_BUFFER) if (!gtp_frame) { #endif - sprintf(buf, "tnotrun:0;"); + snprintf(buf, bufmax, "tnotrun:0;"); buf += 10; size += 10; + bufmax -= 10; } else if (!tpe || (tpe && tpe->reason == gtp_stop_normal)) { - sprintf(buf, "tstop:0;"); + snprintf(buf, bufmax, "tstop:0;"); buf += 8; size += 8; + bufmax -= 8; } else { char outtmp[100]; switch (tpe->reason) { case gtp_stop_frame_full: - sprintf(buf, "tfull:%lx;", - (unsigned long)tpe->num); + snprintf(buf, bufmax, "tfull:%lx;", + (unsigned long)tpe->num); break; case gtp_stop_efault: - sprintf(buf, "terror:%s:%lx;", - string2hex("read memory false", outtmp), - (unsigned long)tpe->num); + snprintf(buf, bufmax, "terror:%s:%lx;", + string2hex("read memory false", outtmp), + (unsigned long)tpe->num); break; case gtp_stop_access_wrong_reg: - sprintf(buf, "terror:%s:%lx;", - string2hex("access wrong register", outtmp), - (unsigned long)tpe->num); + snprintf(buf, bufmax, "terror:%s:%lx;", + string2hex("access wrong register", outtmp), + (unsigned long)tpe->num); break; case gtp_stop_agent_expr_code_error: - sprintf(buf, "terror:%s:%lx;", - string2hex("agent expression code error", - outtmp), - (unsigned long)tpe->num); + snprintf(buf, bufmax, "terror:%s:%lx;", + string2hex("agent expression code error", + outtmp), + (unsigned long)tpe->num); break; case gtp_stop_agent_expr_stack_overflow: - sprintf(buf, "terror:%s:%lx;", + snprintf(buf, bufmax, "terror:%s:%lx;", string2hex("agent expression stack overflow", outtmp), (unsigned long)tpe->num); @@ -6447,6 +6474,7 @@ } size += strlen(buf); + bufmax -= strlen(buf); buf += strlen(buf); } @@ -6528,28 +6556,31 @@ #endif } - sprintf(buf, "tframes:%x;", tfnum); + snprintf(buf, bufmax, "tframes:%x;", tfnum); size += strlen(buf); + bufmax -= strlen(buf); buf += strlen(buf); - sprintf(buf, "tcreated:%x;", atomic_read(>p_frame_create)); + snprintf(buf, bufmax, "tcreated:%x;", atomic_read(>p_frame_create)); size += strlen(buf); + bufmax -= strlen(buf); buf += strlen(buf); #ifdef GTP_FRAME_SIMPLE - sprintf(buf, "tsize:%x;", GTP_FRAME_SIZE); + snprintf(buf, bufmax, "tsize:%x;", GTP_FRAME_SIZE); #endif #ifdef GTP_FTRACE_RING_BUFFER if (gtp_frame) - sprintf(buf, "tsize:%lx;", ring_buffer_size(gtp_frame)); + snprintf(buf, bufmax, "tsize:%lx;", ring_buffer_size(gtp_frame)); else - sprintf(buf, "tsize:%x;", GTP_FRAME_SIZE * num_online_cpus()); + snprintf(buf, bufmax, "tsize:%x;", GTP_FRAME_SIZE * num_online_cpus()); #endif #ifdef GTP_RB - sprintf(buf, "tsize:%lx;", - gtp_rb_page_count * GTP_RB_DATA_MAX * num_online_cpus()); + snprintf(buf, bufmax, "tsize:%lx;", + gtp_rb_page_count * GTP_RB_DATA_MAX * num_online_cpus()); #endif size += strlen(buf); + bufmax -= strlen(buf); buf += strlen(buf); #ifdef GTP_FRAME_SIMPLE @@ -6590,16 +6621,19 @@ * num_online_cpus(); } #endif - sprintf(buf, "tfree:%lx;", (unsigned long)tmpaddr); + snprintf(buf, bufmax, "tfree:%lx;", (unsigned long)tmpaddr); size += strlen(buf); + bufmax -= strlen(buf); buf += strlen(buf); - sprintf(buf, "circular:%x;", gtp_circular); + snprintf(buf, bufmax, "circular:%x;", gtp_circular); size += strlen(buf); + bufmax -= strlen(buf); buf += strlen(buf); - sprintf(buf, "disconn:%x", gtp_disconnected_tracing); + snprintf(buf, bufmax, "disconn:%x", gtp_disconnected_tracing); size += strlen(buf); + bufmax -= strlen(buf); buf += strlen(buf); return size; @@ -6619,41 +6653,53 @@ if (gtp_start && tpe) /* Tpe is stop, stop all tpes. */ gtp_gdbrsp_qtstop(); - sprintf(gtp_rw_bufp, "T%x;", gtp_start ? 1 : 0); + snprintf(gtp_rw_bufp, GTP_RW_BUFP_MAX, "T%x;", gtp_start ? 1 : 0); gtp_rw_bufp += 3; gtp_rw_size += 3; - tmp = gtp_get_status(tpe, gtp_rw_bufp); + tmp = gtp_get_status(tpe, gtp_rw_bufp, GTP_RW_BUFP_MAX); gtp_rw_bufp += tmp; gtp_rw_size += tmp; return 1; } + +#define GTP_REPORT_TRACEPOINT_MAX (1 + 16 + 1 + 16 + 1 + 1 + 1 + \ + 20 + 1 + 16 + 1) static void -gtp_report_tracepoint(struct gtp_entry *gtp, char *buf) -{ - sprintf(buf, "T%lx:%lx:%c:%d:%lx", (unsigned long)gtp->num, - (unsigned long)gtp->addr, (gtp->disable ? 'D' : 'E'), - gtp->step, (unsigned long)gtp->pass); +gtp_report_tracepoint(struct gtp_entry *gtp, char *buf, int bufmax) +{ + snprintf(buf, bufmax, "T%lx:%lx:%c:%d:%lx", (unsigned long)gtp->num, + (unsigned long)gtp->addr, (gtp->disable ? 'D' : 'E'), + gtp->step, (unsigned long)gtp->pass); +} + +static int +gtp_report_action_max(struct gtp_entry *gtp, struct action *action) +{ + return (1 + 16 + 1 + 16 + 1 + strlen(action->src) + 1); } static void -gtp_report_action(struct gtp_entry *gtp, struct action *action, char *buf) -{ - sprintf(buf, "A%lx:%lx:%s", - (unsigned long)gtp->num, - (unsigned long)gtp->addr, - action->src); +gtp_report_action(struct gtp_entry *gtp, struct action *action, char *buf, + int bufmax) +{ + snprintf(buf, bufmax, "A%lx:%lx:%s", (unsigned long)gtp->num, + (unsigned long)gtp->addr, action->src); +} + +static int +gtp_report_src_max(struct gtp_entry *gtp, struct gtpsrc *src) +{ + return (1 + 16 + 1 + 16 + 1 + strlen(src->src) + 1); } static void -gtp_report_src(struct gtp_entry *gtp, struct gtpsrc *src, char *buf) -{ - sprintf(buf, "Z%lx:%lx:%s", - (unsigned long)gtp->num, - (unsigned long)gtp->addr, - src->src);+gtp_report_src(struct gtp_entry *gtp, struct gtpsrc *src, char *buf, int bufmax)
+{ + snprintf(buf, bufmax, "Z%lx:%lx:%s", (unsigned long)gtp->num, + (unsigned long)gtp->addr, src->src); } static void @@ -6677,15 +6723,18 @@ { if (gtp_list) { current_gtp = gtp_list; - gtp_report_tracepoint(current_gtp, gtp_rw_bufp); + gtp_report_tracepoint(current_gtp, gtp_rw_bufp, + GTP_RW_BUFP_MAX); gtp_rw_size += strlen(gtp_rw_bufp); gtp_rw_bufp += strlen(gtp_rw_bufp); current_gtp_action = current_gtp->action_list; gtp_current_action_check(); } else { - gtp_rw_bufp[0] = 'l'; - gtp_rw_size += 1; - gtp_rw_bufp += 1; + if (GTP_RW_BUFP_MAX > 1) { + gtp_rw_bufp[0] = 'l'; + gtp_rw_size += 1; + gtp_rw_bufp += 1; + } } return 1; @@ -6696,7 +6745,7 @@ { if (current_gtp_action) { gtp_report_action(current_gtp, current_gtp_action, - gtp_rw_bufp); + gtp_rw_bufp, GTP_RW_BUFP_MAX); gtp_rw_size += strlen(gtp_rw_bufp); gtp_rw_bufp += strlen(gtp_rw_bufp); current_gtp_action = current_gtp_action->next; @@ -6705,7 +6754,8 @@ } if (current_gtp_src) { - gtp_report_src(current_gtp, current_gtp_src, gtp_rw_bufp); + gtp_report_src(current_gtp, current_gtp_src, gtp_rw_bufp, + GTP_RW_BUFP_MAX); gtp_rw_size += strlen(gtp_rw_bufp); gtp_rw_bufp += strlen(gtp_rw_bufp); current_gtp_src = current_gtp_src->next; @@ -6714,15 +6764,18 @@ } if (current_gtp) { - gtp_report_tracepoint(current_gtp, gtp_rw_bufp); + gtp_report_tracepoint(current_gtp, gtp_rw_bufp, + GTP_RW_BUFP_MAX); gtp_rw_size += strlen(gtp_rw_bufp); gtp_rw_bufp += strlen(gtp_rw_bufp); current_gtp_action = current_gtp->action_list; gtp_current_action_check(); } else { - gtp_rw_bufp[0] = 'l'; - gtp_rw_size += 1; - gtp_rw_bufp += 1; + if (GTP_RW_BUFP_MAX > 1) { + gtp_rw_bufp[0] = 'l'; + gtp_rw_size += 1; + gtp_rw_bufp += 1; + } } out: return 1; @@ -6731,8 +6784,8 @@ static void gtp_report_var(void) { - sprintf(gtp_rw_bufp, "%x:%s", current_gtp_var->num, - current_gtp_var->src); + snprintf(gtp_rw_bufp, GTP_RW_BUFP_MAX, "%x:%s", current_gtp_var->num, + current_gtp_var->src); gtp_rw_size += strlen(gtp_rw_bufp); gtp_rw_bufp += strlen(gtp_rw_bufp); } @@ -6747,9 +6800,11 @@ gtp_report_var(); current_gtp_var = current_gtp_var->next; } else { - gtp_rw_bufp[0] = 'l'; - gtp_rw_size += 1; - gtp_rw_bufp += 1; + if (GTP_RW_BUFP_MAX > 1) { + gtp_rw_bufp[0] = 'l'; + gtp_rw_size += 1; + gtp_rw_bufp += 1; + } } return 1; @@ -6937,15 +6992,17 @@ out: if (var || vr) { output_value: - sprintf(gtp_rw_bufp, "V%08x%08x", - (unsigned int) (val >> 32), - (unsigned int) (val & 0xffffffff)); + snprintf(gtp_rw_bufp, GTP_RW_BUFP_MAX, "V%08x%08x", + (unsigned int) (val >> 32), + (unsigned int) (val & 0xffffffff)); gtp_rw_size += strlen(gtp_rw_bufp); gtp_rw_bufp += strlen(gtp_rw_bufp); } else { - gtp_rw_bufp[0] = 'U'; - gtp_rw_size += 1; - gtp_rw_bufp += 1; + if (GTP_RW_BUFP_MAX > 1) { + gtp_rw_bufp[0] = 'U'; + gtp_rw_size += 1; + gtp_rw_bufp += 1; + } } return 1; @@ -7112,14 +7169,17 @@ if (len == 0) return -EINVAL; + if (GTP_RW_BUFP_MAX < 10) + return -EINVAL; + if (offset == 0) { int ret = gtp_traceframe_info_get(); if (ret != 0) return ret; } - if (len > GTP_RW_MAX - 4 - gtp_rw_size) - len = GTP_RW_MAX - 4 - gtp_rw_size; + if (len > GTP_RW_BUFP_MAX - 1) + len = GTP_RW_BUFP_MAX - 1; if (len >= gtp_traceframe_info_len - offset) { len = gtp_traceframe_info_len - offset; @@ -7127,9 +7187,11 @@ gtp_rw_size += 1; gtp_rw_bufp += 1; } else { - gtp_rw_bufp[0] = 'm'; - gtp_rw_size += 1; - gtp_rw_bufp += 1; + if (GTP_RW_BUFP_MAX > 1) { + gtp_rw_bufp[0] = 'm'; + gtp_rw_size += 1; + gtp_rw_bufp += 1; + } } memcpy(gtp_rw_bufp, gtp_traceframe_info + offset, len); @@ -7159,7 +7221,7 @@ if (len == 0) return -EINVAL; len &= 0xffff; - len = (ULONGEST) min((int)((GTP_RW_MAX - 4 - gtp_rw_size) / 2), + len = (ULONGEST) min((int)(GTP_RW_BUFP_MAX / 2), (int)len); #ifdef GTP_DEBUG @@ -7375,7 +7437,7 @@ #endif struct pt_regs *regs; - if (GTP_RW_MAX - 4 - gtp_rw_size < GTP_REG_ASCII_SIZE) + if (GTP_RW_BUFP_MAX < GTP_REG_ASCII_SIZE) return -E2BIG; #ifdef GTP_FRAME_SIMPLE @@ -7667,7 +7729,7 @@ ret = 1; switch (rsppkg[0]) { case '?': - strcpy(gtp_rw_bufp, "S05"); + snprintf(gtp_rw_bufp, GTP_RW_BUFP_MAX, "S05"); gtp_rw_bufp += 3; gtp_rw_size += 3; break; @@ -7686,15 +7748,15 @@ ret = gtp_gdbrsp_qT(rsppkg + 2); else if (strncmp("qSupported", rsppkg, 10) == 0) { #ifdef GTP_RB - strcpy(gtp_rw_bufp, - "ConditionalTracepoints+;" - "TracepointSource+;DisconnectedTracing+;" - "qXfer:traceframe-info:read+;"); + snprintf(gtp_rw_bufp, GTP_RW_BUFP_MAX, + "ConditionalTracepoints+;" + "TracepointSource+;DisconnectedTracing+;" + "qXfer:traceframe-info:read+;"); #endif #if defined(GTP_FRAME_SIMPLE) || defined(GTP_FTRACE_RING_BUFFER) - strcpy(gtp_rw_bufp, - "ConditionalTracepoints+;" - "TracepointSource+;DisconnectedTracing+;"); + snprintf(gtp_rw_bufp, GTP_RW_BUFP_MAX, + "ConditionalTracepoints+;" + "TracepointSource+;DisconnectedTracing+;"); #endif gtp_rw_size += strlen(gtp_rw_bufp); gtp_rw_bufp += strlen(gtp_rw_bufp); @@ -7715,11 +7777,11 @@ break; } if (ret == 0) { - strcpy(gtp_rw_bufp, "OK"); + snprintf(gtp_rw_bufp, GTP_RW_BUFP_MAX, "OK"); gtp_rw_bufp += 2; gtp_rw_size += 2; } else if (ret < 0) { - sprintf(gtp_rw_bufp, "E%02x", -ret); + snprintf(gtp_rw_bufp, GTP_RW_BUFP_MAX, "E%02x", -ret); gtp_rw_bufp += 3; gtp_rw_size += 3; } @@ -8057,7 +8119,6 @@ struct gtp_entry *tpe; struct gtp_var *tvar; int tmpsize; - char tmpbuf[200]; int ret = -1; /* Head. */ @@ -8065,40 +8126,35 @@ strcpy(wbuf, "\x7fTRACE0\n"); /* BUG: will be a new value. */ - snprintf(tmpbuf, 200, "R %x\n", GTP_REG_BIN_SIZE); - wbuf = gtp_realloc(grs, strlen(tmpbuf), 0); + wbuf = gtp_realloc(grs, 100, 0); if (!wbuf) goto out; - strcpy(wbuf, tmpbuf); - - strcpy(tmpbuf, "status 0;"); - wbuf = gtp_realloc(grs, strlen(tmpbuf), 0); - if (!wbuf) + snprintf(wbuf, 100, "R %x\n", GTP_REG_BIN_SIZE); + gtp_realloc_sub_size(grs, 100 - strlen(wbuf)); + + if (gtp_realloc_str(grs, "status 0;", 0)) goto out; - strcpy(wbuf, tmpbuf); - + + wbuf = gtp_realloc(grs, 300, 0); + if (!wbuf) + goto out; for (tpe = gtp_list; tpe; tpe = tpe->next) { if (tpe->reason != gtp_stop_normal) break; } - tmpsize = gtp_get_status(tpe, tmpbuf); - wbuf = gtp_realloc(grs, tmpsize, 0); - if (!wbuf) - goto out; - memcpy(wbuf, tmpbuf, tmpsize); - - wbuf = gtp_realloc(grs, 1, 0); - if (!wbuf) + tmpsize = gtp_get_status(tpe, wbuf, 300); + gtp_realloc_sub_size(grs, 300 - tmpsize); + + if (gtp_realloc_str(grs, "\n", 0)) goto out; - wbuf[0] = '\n'; /* Tval. */ for (tvar = gtp_var_list; tvar; tvar = tvar->next) { - snprintf(tmpbuf, 200, "tsv %x:%s\n", tvar->num, tvar->src); - wbuf = gtp_realloc(grs, strlen(tmpbuf), 0); + wbuf = gtp_realloc(grs, 200, 0); if (!wbuf) goto out; - strcpy(wbuf, tmpbuf); + snprintf(wbuf, 200, "tsv %x:%s\n", tvar->num, tvar->src); + gtp_realloc_sub_size(grs, 200 - strlen(wbuf)); } /* Tracepoint. */ @@ -8107,36 +8163,46 @@ struct gtpsrc *src; /* Tpe. */ - gtp_report_tracepoint(tpe, tmpbuf); - wbuf = gtp_realloc(grs, strlen(tmpbuf) + 5, 0); + if (gtp_realloc_str(grs, "tp ", 0)) + goto out; + wbuf = gtp_realloc(grs, GTP_REPORT_TRACEPOINT_MAX, 0); if (!wbuf) goto out; - sprintf(wbuf, "tp %s\n", tmpbuf); - grs->size -= 1; + gtp_report_tracepoint(tpe, wbuf, GTP_REPORT_TRACEPOINT_MAX); + gtp_realloc_sub_size(grs, + GTP_REPORT_TRACEPOINT_MAX - strlen(wbuf)); + if (gtp_realloc_str(grs, "\n", 0)) + goto out; /* Action. */ for (ae = tpe->action_list; ae; ae = ae->next) { - gtp_report_action(tpe, ae, tmpbuf); - wbuf = gtp_realloc(grs, strlen(tmpbuf) + 5, 0); + if (gtp_realloc_str(grs, "tp ", 0)) + goto out; + tmpsize = gtp_report_action_max(tpe, ae); + wbuf = gtp_realloc(grs, tmpsize, 0); if (!wbuf) goto out; - sprintf(wbuf, "tp %s\n", tmpbuf); - grs->size -= 1; + gtp_report_action(tpe, ae, wbuf, tmpsize); + gtp_realloc_sub_size(grs, tmpsize - strlen(wbuf)); + if (gtp_realloc_str(grs, "\n", 0)) + goto out; } /* Src. */ for (src = tpe->src; src; src = src->next) { - gtp_report_src(tpe, src, tmpbuf); - wbuf = gtp_realloc(grs, strlen(tmpbuf) + 5, 0); + if (gtp_realloc_str(grs, "tp ", 0)) + goto out; + tmpsize = gtp_report_src_max(tpe, src); + wbuf = gtp_realloc(grs, tmpsize, 0); if (!wbuf) goto out; - sprintf(wbuf, "tp %s\n", tmpbuf); - grs->size -= 1; + gtp_report_src(tpe, src, wbuf, tmpsize); + gtp_realloc_sub_size(grs, tmpsize - strlen(wbuf)); + if (gtp_realloc_str(grs, "\n", 0)) + goto out; } } - wbuf = gtp_realloc(grs, 1, is_end); - if (!wbuf) + if (gtp_realloc_str(grs, "\n", is_end)) goto out; - wbuf[0] = '\n'; ret = 0; out: @@ -8594,7 +8660,8 @@ struct gtp_rb_walk_s rbws; struct gtp_realloc_s *grs = gps->grs; #endif - grs->size = 0; + /* Because this function only be called when gtp_realloc_is_empty, + so grs don't need reset. */ #ifdef GTP_RB #define GTP_PIPE_PEEK (cpu = gtpframe_pipe_peek(gps)) @@ -8780,15 +8847,19 @@ size, *ppos); #endif - if (gps->grs->buf == NULL) { + if (!gtp_realloc_is_alloced (gps->grs)) { ret = gtp_realloc_alloc(gps->grs, 200); if (ret != 0) goto out; } else if (*ppos < gps->begin || *ppos >= (gps->begin + gps->grs->size)) { - gps->grs->size = 0; + gtp_realloc_reset(gps->grs); if (gps->llseek_move) { + /* clear user will return NULL. + Then GDB tfind got a fail. */ + if (size > 2) + size = 2; if (clear_user(buf, size)) { ret = -EFAULT; goto out; @@ -8800,7 +8871,7 @@ } } - if (gps->grs->size == 0) { + if (gtp_realloc_is_empty (gps->grs)) { if (*ppos == 0) { if (gtp_frame_file_header(gps->grs, 1)) goto out; @@ -8852,6 +8923,7 @@ if (ret < 0) return ret; + /* True means that GDB tfind to next frame entry. */ if (ret >= gps->begin + gps->grs->size && gps->begin) gps->llseek_move = 1;