From mboxrd@z Thu Jan 1 00:00:00 1970 From: Syd Polk To: Fernando Nasser Cc: insight@sources.redhat.com Subject: Re: Buffer Overflow Patch in GDB/TCL Interface code. Date: Thu, 19 Oct 2000 09:17:00 -0000 Message-id: <39EF1F66.6D763F7F@redhat.com> References: <39EEF758.21EDD4C5@cygnus.com> X-SW-Source: 2000-q4/msg00088.html My only concern is whether this call, asprintf, is available on all platforms. Fernando Nasser wrote: > > Message forwarded in behalf of Steven Johnson > (Steven is not sure if this message made it to the list -- ISP problems. > Please forgive us if you get it in duplicate) > > There are a number of fixed size buffers defined in the C code that acts as an > interface between GDB and the TCL Insight. Unfortunately, on my system some of > those buffers were not big enough, leading to stack corruption and a resultant > segfault. I Specifically had a problem with clearing breakpoints, the problem > was that the path to my source file was quite long, and caused a sprintf to > overflow it's pre-allocated buffer. > > Instead of just adding some more to the buffer, i decided to fix as many of the > pre-allocated buffers as possible, so that this sort of problem can not occur > in future. > > A Couple of fixes were tried. The one I settled on was wholescale replacement > of as many 'sprintf'/'vsprintf' calls with 'asprintf' and 'vasprintf' > respectively, as was possible without serious modification of the existing > code. There are now only 2 or 3 places in gdbtk-cmds where sprintf is used > (Mainly to do with source file loading). Everywhere else has been replaced with > asprintf/vasprintf. > > Given that neither asprintf or vasprintf are in the MAN pages of linux, here is > a brief explenation. > > asprintf (I call it "auto sprintf"): It automatically allocates a buffer of the > correct size to hold the sprintf'd string. The buffer when finished with must > be discarded with "free", otherwise you will get a heap leak. > > vasprintf is the same as vsprintf, except it too automatically allocates its > buffer. > > Eg: > > Where code would have once been: > > char buf[1024]; /* This is big enough for any reasonable use I reckon. */ > sprintf(buf,"my %s %s %s %s %s undetermined length string",s1,s2,s3,s4,s5); > > it is written as: > > char *buf; > sprintf(&buf,"my %s %s %s %s %s undetermined length string",s1,s2,s3,s4,s5); > > /* I have now finished with buf, so... */ > free(buf); > > The big difference is you no longer have to guess the size of your buffer, so > no more stack corruption can result. > > It has been used elsewhere in GDB/Insight (remote.c and MI) to name a couple, > ergo, "it's portable". If it isn't really portable, then I would suggest adding > a local copy to utils.c in GDB for targets that do not support it. > > Anyway, here comes the changelog and patch: > 12345678901234567890123456789012345678901234567890123456789012345678901234567890 > 2000-10-19 Steven Johnson > > * gdbtk.c,gdbtk-cmds.c,gdbtk-hooks.c,gdbtk-variable.c > : Replaced the vast majority of sprintf/vsprintf calls > with asprintf and vasprintf respectively. Should > prevent any possible buffer overruns possible with > fixed size sprintf buffers. Specifically fixes a > problem with long filenames and clearing breakpoints > overflowing their buffers when using sprintf, causing > a segfault. Generically should also prevent any other > similar problems from occuring. > > diff -C2 -r -b ../gdb_cvs/src/gdb/gdbtk/generic/gdbtk-cmds.c > src/gdb/gdbtk/generic/gdbtk-cmds.c > *** ../gdb_cvs/src/gdb/gdbtk/generic/gdbtk-cmds.c Mon Aug 21 08:59:40 > 2000 > --- src/gdb/gdbtk/generic/gdbtk-cmds.c Thu Oct 19 11:25:10 2000 > *************** > *** 546,556 **** > { > va_list args; > ! char buf[1024]; > > va_start (args, format); > > ! vsprintf (buf, format, args); > > Tcl_ListObjAppendElement (NULL, objp, Tcl_NewStringObj (buf, -1)); > } > > --- 546,557 ---- > { > va_list args; > ! char *buf; > > va_start (args, format); > > ! vasprintf (&buf, format, args); > > Tcl_ListObjAppendElement (NULL, objp, Tcl_NewStringObj (buf, -1)); > + free(buf); > } > > *************** > *** 2009,2016 **** > Tcl_Obj *CONST objv[]; > { > ! char buff[64]; > > ! sprintf (buff, "0x%llx", (long long) read_register (PC_REGNUM)); > Tcl_SetStringObj (result_ptr->obj_ptr, buff, -1); > return TCL_OK; > } > --- 2010,2018 ---- > Tcl_Obj *CONST objv[]; > { > ! char *buff; > > ! asprintf (&buff, "0x%llx", (long long) read_register (PC_REGNUM)); > Tcl_SetStringObj (result_ptr->obj_ptr, buff, -1); > + free(buff); > return TCL_OK; > } > *************** > *** 2181,2187 **** > if (tp == NULL) > { > ! char buff[64]; > ! sprintf (buff, "Tracepoint #%d does not exist", tpnum); > Tcl_SetStringObj (result_ptr->obj_ptr, buff, -1); > return TCL_ERROR; > } > --- 2183,2190 ---- > if (tp == NULL) > { > ! char *buff; > ! asprintf (&buff, "Tracepoint #%d does not exist", tpnum); > Tcl_SetStringObj (result_ptr->obj_ptr, buff, -1); > + free(buff); > return TCL_ERROR; > } > *************** > *** 2598,2609 **** > > if (ret_val == TCL_OK) { > ! char buffer[256]; > Tcl_Obj *limits_obj[2]; > > ! sprintf (buffer, "0x%s", paddr_nz (low)); > limits_obj[0] = Tcl_NewStringObj (buffer, -1); > > ! sprintf (buffer, "0x%s", paddr_nz (high)); > limits_obj[1] = Tcl_NewStringObj (buffer, -1); > > Tcl_DecrRefCount (result_ptr->obj_ptr); > --- 2601,2614 ---- > > if (ret_val == TCL_OK) { > ! char *buffer; > Tcl_Obj *limits_obj[2]; > > ! asprintf (&buffer, "0x%s", paddr_nz (low)); > limits_obj[0] = Tcl_NewStringObj (buffer, -1); > + free(buffer); > > ! asprintf (&buffer, "0x%s", paddr_nz (high)); > limits_obj[1] = Tcl_NewStringObj (buffer, -1); > + free(buffer); > > Tcl_DecrRefCount (result_ptr->obj_ptr); > *************** > *** 2621,2625 **** > struct disassembly_client_data *client_data = > (struct disassembly_client_data *) clientData; > ! char buffer[18]; > int index_len; > > --- 2626,2630 ---- > struct disassembly_client_data *client_data = > (struct disassembly_client_data *) clientData; > ! char *buffer; > int index_len; > > *************** > *** 2696,2704 **** > will allow us avoid converting widget_line_no into a string. > */ > > ! sprintf (buffer, "%d", client_data->widget_line_no); > > Tcl_SetVar2 (client_data->interp, client_data->map_arr, > Tcl_DStringValue (&client_data->src_to_line_prefix), > buffer, 0); > > Tcl_DStringSetLength (&client_data->src_to_line_prefix, > index_len); > --- 2701,2710 ---- > will allow us avoid converting widget_line_no into a string. > */ > > ! asprintf (&buffer, "%d", client_data->widget_line_no); > > Tcl_SetVar2 (client_data->interp, client_data->map_arr, > Tcl_DStringValue (&client_data->src_to_line_prefix), > buffer, 0); > + free(buffer); > > Tcl_DStringSetLength (&client_data->src_to_line_prefix, > index_len); > *************** > *** 2802,2806 **** > if (*client_data->map_arr != '\0') > { > ! char buffer[16]; > > /* Run the command, then add an entry to the map array in > --- 2808,2812 ---- > if (*client_data->map_arr != '\0') > { > ! char *buffer; > > /* Run the command, then add an entry to the map array in > *************** > *** 2812,2816 **** > will allow us avoid converting widget_line_no into a string. */ > > ! sprintf (buffer, "%d", client_data->widget_line_no); > > Tcl_SetVar2 (client_data->interp, client_data->map_arr, > --- 2818,2822 ---- > will allow us avoid converting widget_line_no into a string. */ > > ! asprintf (&buffer, "%d", client_data->widget_line_no); > > Tcl_SetVar2 (client_data->interp, client_data->map_arr, > *************** > *** 2829,2832 **** > --- 2835,2839 ---- > Tcl_DStringSetLength (&client_data->line_to_pc_prefix, > line_to_pc_len); > > + free(buffer); > } > > *************** > *** 3685,3689 **** > int line, ret, thread = -1; > struct breakpoint *b; > ! char buf[64], *typestr; > Tcl_DString cmd; > enum bpdisp disp; > --- 3692,3696 ---- > int line, ret, thread = -1; > struct breakpoint *b; > ! char *buf, *typestr; > Tcl_DString cmd; > enum bpdisp disp; > *************** > *** 3745,3751 **** > > /* FIXME: this won't work for duplicate basenames! */ > ! sprintf (buf, "%s:%d", basename (Tcl_GetStringFromObj (objv[1], NULL)), > line); > b->addr_string = strsave (buf); > > /* now send notification command back to GUI */ > --- 3752,3759 ---- > > /* FIXME: this won't work for duplicate basenames! */ > ! asprintf (&buf, "%s:%d", basename (Tcl_GetStringFromObj (objv[1], NULL)), > line); > b->addr_string = strsave (buf); > + free(buf); > > /* now send notification command back to GUI */ > *************** > *** 3754,3769 **** > > Tcl_DStringAppend (&cmd, "gdbtk_tcl_breakpoint create ", -1); > ! sprintf (buf, "%d", b->number); > Tcl_DStringAppendElement (&cmd, buf); > ! sprintf (buf, "0x%lx", (long) sal.pc); > Tcl_DStringAppendElement (&cmd, buf); > Tcl_DStringAppendElement (&cmd, Tcl_GetStringFromObj (objv[2], NULL)); > Tcl_DStringAppendElement (&cmd, Tcl_GetStringFromObj (objv[1], NULL)); > Tcl_DStringAppendElement (&cmd, bpdisp[b->disposition]); > ! sprintf (buf, "%d", b->enable); > Tcl_DStringAppendElement (&cmd, buf); > ! sprintf (buf, "%d", b->thread); > Tcl_DStringAppendElement (&cmd, buf); > ! > > ret = Tcl_Eval (interp, Tcl_DStringValue (&cmd)); > --- 3762,3780 ---- > > Tcl_DStringAppend (&cmd, "gdbtk_tcl_breakpoint create ", -1); > ! asprintf (&buf, "%d", b->number); > Tcl_DStringAppendElement (&cmd, buf); > ! free(buf); > ! asprintf (&buf, "0x%lx", (long) sal.pc); > Tcl_DStringAppendElement (&cmd, buf); > Tcl_DStringAppendElement (&cmd, Tcl_GetStringFromObj (objv[2], NULL)); > Tcl_DStringAppendElement (&cmd, Tcl_GetStringFromObj (objv[1], NULL)); > Tcl_DStringAppendElement (&cmd, bpdisp[b->disposition]); > ! free(buf); > ! asprintf (&buf, "%d", b->enable); > Tcl_DStringAppendElement (&cmd, buf); > ! free(buf); > ! asprintf (&buf, "%d", b->thread); > Tcl_DStringAppendElement (&cmd, buf); > ! free(buf); > > ret = Tcl_Eval (interp, Tcl_DStringValue (&cmd)); > *************** > *** 3797,3801 **** > long addr; > struct breakpoint *b; > ! char *filename, *typestr, buf[64]; > Tcl_DString cmd; > enum bpdisp disp; > --- 3808,3812 ---- > long addr; > struct breakpoint *b; > ! char *filename, *typestr, *buf; > Tcl_DString cmd; > enum bpdisp disp; > *************** > *** 3849,3853 **** > b->thread = thread; > > ! sprintf (buf, "*(0x%lx)", addr); > b->addr_string = strsave (buf); > > --- 3860,3864 ---- > b->thread = thread; > > ! asprintf (&buf, "*(0x%lx)", addr); > b->addr_string = strsave (buf); > > *************** > *** 3857,3865 **** > > Tcl_DStringAppend (&cmd, "gdbtk_tcl_breakpoint create ", -1); > ! sprintf (buf, "%d", b->number); > Tcl_DStringAppendElement (&cmd, buf); > ! sprintf (buf, "0x%lx", addr); > Tcl_DStringAppendElement (&cmd, buf); > ! sprintf (buf, "%d", b->line_number); > Tcl_DStringAppendElement (&cmd, buf); > > --- 3868,3879 ---- > > Tcl_DStringAppend (&cmd, "gdbtk_tcl_breakpoint create ", -1); > ! free(buf); > ! asprintf (&buf, "%d", b->number); > Tcl_DStringAppendElement (&cmd, buf); > ! free(buf); > ! asprintf (&buf, "0x%lx", addr); > Tcl_DStringAppendElement (&cmd, buf); > ! free(buf); > ! asprintf (&buf, "%d", b->line_number); > Tcl_DStringAppendElement (&cmd, buf); > > *************** > *** 3869,3879 **** > Tcl_DStringAppendElement (&cmd, filename); > Tcl_DStringAppendElement (&cmd, bpdisp[b->disposition]); > ! sprintf (buf, "%d", b->enable); > Tcl_DStringAppendElement (&cmd, buf); > ! sprintf (buf, "%d", b->thread); > Tcl_DStringAppendElement (&cmd, buf); > > ret = Tcl_Eval (interp, Tcl_DStringValue (&cmd)); > Tcl_DStringFree (&cmd); > return ret; > } > --- 3883,3896 ---- > Tcl_DStringAppendElement (&cmd, filename); > Tcl_DStringAppendElement (&cmd, bpdisp[b->disposition]); > ! free(buf); > ! asprintf (&buf, "%d", b->enable); > Tcl_DStringAppendElement (&cmd, buf); > ! free(buf); > ! asprintf (&buf, "%d", b->thread); > Tcl_DStringAppendElement (&cmd, buf); > > ret = Tcl_Eval (interp, Tcl_DStringValue (&cmd)); > Tcl_DStringFree (&cmd); > + free(buf); > return ret; > } > *************** > *** 4014,4020 **** > if (!b || b->type != bp_breakpoint) > { > ! char err_buf[64]; > ! sprintf (err_buf, "Breakpoint #%d does not exist.", bpnum); > Tcl_SetStringObj (result_ptr->obj_ptr, err_buf, -1); > return TCL_ERROR; > } > --- 4031,4038 ---- > if (!b || b->type != bp_breakpoint) > { > ! char *err_buf; > ! asprintf (&err_buf, "Breakpoint #%d does not exist.", bpnum); > Tcl_SetStringObj (result_ptr->obj_ptr, err_buf, -1); > + free(err_buf); > return TCL_ERROR; > } > *************** > *** 4309,4321 **** > Tcl_Obj *CONST objv[]; > { > ! char frame[32]; > > if (selected_frame == NULL) > ! strcpy (frame, ""); > else > ! sprintf (frame, "0x%s", paddr_nz (FRAME_FP (selected_frame))); > > Tcl_SetStringObj (result_ptr->obj_ptr, frame, -1); > > return TCL_OK; > } > --- 4327,4340 ---- > Tcl_Obj *CONST objv[]; > { > ! char *frame; > > if (selected_frame == NULL) > ! asprintf (&frame, "%s",""); > else > ! asprintf (&frame, "0x%s", paddr_nz (FRAME_FP (selected_frame))); > > Tcl_SetStringObj (result_ptr->obj_ptr, frame, -1); > > + free(frame); > return TCL_OK; > } > *************** > *** 4339,4349 **** > Tcl_Obj *CONST objv[]; > { > ! char start[32]; > ! char end[32]; > > if (selected_frame == NULL) > { > ! strcpy (start, ""); > ! strcpy (end, ""); > } > else > --- 4358,4368 ---- > Tcl_Obj *CONST objv[]; > { > ! char *start = NULL; > ! char *end = NULL; > > if (selected_frame == NULL) > { > ! asprintf (&start, "%s", ""); > ! asprintf (&end, "%s", ""); > } > else > *************** > *** 4351,4356 **** > struct block *block; > block = get_frame_block (selected_frame); > ! sprintf (start, "0x%s", paddr_nz (BLOCK_START (block))); > ! sprintf (end, "0x%s", paddr_nz (BLOCK_END (block))); > } > > --- 4370,4375 ---- > struct block *block; > block = get_frame_block (selected_frame); > ! asprintf (&start, "0x%s", paddr_nz (BLOCK_START (block))); > ! asprintf (&end, "0x%s", paddr_nz (BLOCK_END (block))); > } > > *************** > *** 4361,4364 **** > --- 4380,4385 ---- > Tcl_NewStringObj (end, -1)); > > + free(start); > + free(end); > return TCL_OK; > } > *************** > *** 4436,4449 **** > if (!junk && pc < BLOCK_END (block)) > { > ! char addr[32]; > > Tcl_Obj *elt = Tcl_NewListObj (0, NULL); > ! sprintf (addr, "0x%s", paddr_nz (BLOCK_START (block))); > Tcl_ListObjAppendElement (interp, elt, > Tcl_NewStringObj (addr, -1)); > ! sprintf (addr, "0x%s", paddr_nz (BLOCK_END (block))); > Tcl_ListObjAppendElement (interp, elt, > Tcl_NewStringObj (addr, -1)); > Tcl_ListObjAppendElement (interp, result_ptr->obj_ptr, elt); > } > > --- 4457,4472 ---- > if (!junk && pc < BLOCK_END (block)) > { > ! char *addr; > > Tcl_Obj *elt = Tcl_NewListObj (0, NULL); > ! asprintf (&addr, "0x%s", paddr_nz (BLOCK_START (block))); > Tcl_ListObjAppendElement (interp, elt, > Tcl_NewStringObj (addr, -1)); > ! free(addr); > ! asprintf (&addr, "0x%s", paddr_nz (BLOCK_END (block))); > Tcl_ListObjAppendElement (interp, elt, > Tcl_NewStringObj (addr, -1)); > Tcl_ListObjAppendElement (interp, result_ptr->obj_ptr, elt); > + free(addr); > } > > diff -C2 -r -b ../gdb_cvs/src/gdb/gdbtk/generic/gdbtk-hooks.c > src/gdb/gdbtk/generic/gdbtk-hooks.c > *** ../gdb_cvs/src/gdb/gdbtk/generic/gdbtk-hooks.c Thu Jul 13 09:10:03 > 2000 > --- src/gdb/gdbtk/generic/gdbtk-hooks.c Thu Oct 19 10:54:06 2000 > *************** > *** 293,300 **** > va_list args; > { > ! char buf[200]; > > ! vsprintf (buf, warning, args); > gdbtk_two_elem_cmd ("gdbtk_tcl_warning", buf); > } > > --- 293,302 ---- > va_list args; > { > ! char *buf; > > ! vasprintf (&buf, warning, args); > gdbtk_two_elem_cmd ("gdbtk_tcl_warning", buf); > + > + free(buf); > } > > *************** > *** 326,333 **** > const char *warning; > { > ! char buf[512]; > ! sprintf (buf, "gdbtk_tcl_ignorable_warning {%s} {%s}", class, warning); > if (Tcl_Eval (gdbtk_interp, buf) != TCL_OK) > report_error (); > } > > --- 328,336 ---- > const char *warning; > { > ! char *buf; > ! asprintf (&buf, "gdbtk_tcl_ignorable_warning {%s} {%s}", class, warning); > if (Tcl_Eval (gdbtk_interp, buf) != TCL_OK) > report_error (); > + free(buf); > } > > *************** > *** 460,468 **** > { > va_list args; > ! char buf[200]; > > va_start (args, format); > ! vsprintf (buf, format, args); > gdbtk_two_elem_cmd ("gdbtk_tcl_readline_begin", buf); > } > > --- 466,475 ---- > { > va_list args; > ! char *buf; > > va_start (args, format); > ! vasprintf (&buf, format, args); > gdbtk_two_elem_cmd ("gdbtk_tcl_readline_begin", buf); > + free(buf); > } > > *************** > *** 529,533 **** > Tcl_DString cmd; > char *p; > ! char buffer[30]; > > Tcl_DStringInit (&cmd); > --- 536,540 ---- > Tcl_DString cmd; > char *p; > ! char *buffer = NULL; > > Tcl_DStringInit (&cmd); > *************** > *** 541,545 **** > { > char *q = strchr (p, ' '); > ! char save; > if (q) > { > --- 548,552 ---- > { > char *q = strchr (p, ' '); > ! char save = '\0'; > if (q) > { > *************** > *** 572,581 **** > case var_uinteger: > case var_zinteger: > ! sprintf (buffer, "%u", *(unsigned int *) cmdblk->var); > Tcl_DStringAppendElement (&cmd, buffer); > break; > > case var_integer: > ! sprintf (buffer, "%d", *(int *) cmdblk->var); > Tcl_DStringAppendElement (&cmd, buffer); > break; > --- 579,588 ---- > case var_uinteger: > case var_zinteger: > ! asprintf (&buffer, "%u", *(unsigned int *) cmdblk->var); > Tcl_DStringAppendElement (&cmd, buffer); > break; > > case var_integer: > ! asprintf (&buffer, "%d", *(int *) cmdblk->var); > Tcl_DStringAppendElement (&cmd, buffer); > break; > *************** > *** 591,594 **** > --- 598,606 ---- > > Tcl_DStringFree (&cmd); > + > + if (buffer != NULL) > + { > + free(buffer); > + } > } > > *************** > *** 631,635 **** > const char *action; > { > ! char buf[256]; > int v; > struct symtab_and_line sal; > --- 643,647 ---- > const char *action; > { > ! char *buf; > int v; > struct symtab_and_line sal; > *************** > *** 646,650 **** > filename = ""; > > ! sprintf (buf, "gdbtk_tcl_breakpoint %s %d 0x%lx %d {%s} {%s} %d %d", > action, b->number, (long) b->address, b->line_number, filename, > bpdisp[b->disposition], b->enable, b->thread); > --- 658,662 ---- > filename = ""; > > ! asprintf (&buf, "gdbtk_tcl_breakpoint %s %d 0x%lx %d {%s} {%s} %d %d", > action, b->number, (long) b->address, b->line_number, filename, > bpdisp[b->disposition], b->enable, b->thread); > *************** > *** 652,655 **** > --- 664,668 ---- > if (Tcl_Eval (gdbtk_interp, buf) != TCL_OK) > report_error (); > + free(buf); > } > > *************** > *** 657,664 **** > gdbtk_load_hash (const char *section, unsigned long num) > { > ! char buf[128]; > ! sprintf (buf, "Download::download_hash %s %ld", section, num); > if (Tcl_Eval (gdbtk_interp, buf) != TCL_OK) > report_error (); > return atoi (gdbtk_interp->result); > } > --- 670,679 ---- > gdbtk_load_hash (const char *section, unsigned long num) > { > ! char *buf; > ! asprintf (&buf, "Download::download_hash %s %ld", section, num); > if (Tcl_Eval (gdbtk_interp, buf) != TCL_OK) > report_error (); > + free(buf); > + > return atoi (gdbtk_interp->result); > } > *************** > *** 712,720 **** > va_list args; > { > ! char buf[200]; > long val; > > ! vsprintf (buf, query, args); > gdbtk_two_elem_cmd ("gdbtk_tcl_query", buf); > > val = atol (gdbtk_interp->result); > --- 727,736 ---- > va_list args; > { > ! char *buf; > long val; > > ! vasprintf (&buf, query, args); > gdbtk_two_elem_cmd ("gdbtk_tcl_query", buf); > + free(buf); > > val = atol (gdbtk_interp->result); > *************** > *** 760,764 **** > const char *action; > { > ! char buf[256]; > int v; > struct symtab_and_line sal; > --- 776,780 ---- > const char *action; > { > ! char *buf; > int v; > struct symtab_and_line sal; > *************** > *** 772,780 **** > if (filename == NULL) > filename = "N/A"; > ! sprintf (buf, "gdbtk_tcl_tracepoint %s %d 0x%lx %d {%s} %d", action, > tp->number, > (long) tp->address, sal.line, filename, tp->pass_count); > > if (Tcl_Eval (gdbtk_interp, buf) != TCL_OK) > report_error (); > } > > --- 788,797 ---- > if (filename == NULL) > filename = "N/A"; > ! asprintf (&buf, "gdbtk_tcl_tracepoint %s %d 0x%lx %d {%s} %d", action, > tp->number, > (long) tp->address, sal.line, filename, tp->pass_count); > > if (Tcl_Eval (gdbtk_interp, buf) != TCL_OK) > report_error (); > + free(buf); > } > > *************** > *** 877,881 **** > gdbtk_annotate_signal () > { > ! char buf[128]; > > /* Inform gui that the target has stopped. This is > --- 894,898 ---- > gdbtk_annotate_signal () > { > ! char *buf; > > /* Inform gui that the target has stopped. This is > *************** > *** 885,892 **** > Tcl_Eval (gdbtk_interp, "gdbtk_stop_idle_callback"); > > ! sprintf (buf, "gdbtk_signal %s {%s}", target_signal_to_name (stop_signal), > target_signal_to_string (stop_signal)); > if (Tcl_Eval (gdbtk_interp, buf) != TCL_OK) > report_error (); > } > > --- 902,910 ---- > Tcl_Eval (gdbtk_interp, "gdbtk_stop_idle_callback"); > > ! asprintf (&buf, "gdbtk_signal %s {%s}", target_signal_to_name > (stop_signal), > target_signal_to_string (stop_signal)); > if (Tcl_Eval (gdbtk_interp, buf) != TCL_OK) > report_error (); > + free(buf); > } > > diff -C2 -r -b ../gdb_cvs/src/gdb/gdbtk/generic/gdbtk-variable.c > src/gdb/gdbtk/generic/gdbtk-variable.c > *** ../gdb_cvs/src/gdb/gdbtk/generic/gdbtk-variable.c Thu Jul 13 09:10:03 > 2000 > --- src/gdb/gdbtk/generic/gdbtk-variable.c Thu Oct 19 11:18:26 2000 > *************** > *** 566,570 **** > gdb_variable *var; > char *name; > ! char obj_name[31]; > int index; > static int id = 0; > --- 566,570 ---- > gdb_variable *var; > char *name; > ! char *obj_name; > int index; > static int id = 0; > *************** > *** 587,596 **** > /* generate a name for this object */ > id++; > ! sprintf (obj_name, "var%d", id); > } > else > { > /* specified name for object */ > ! strncpy (obj_name, name, 30); > objv++; > objc--; > --- 587,596 ---- > /* generate a name for this object */ > id++; > ! asprintf (&obj_name, "var%d", id); > } > else > { > /* specified name for object */ > ! asprintf (&obj_name, "%s", name); > objv++; > objc--; > *************** > *** 648,651 **** > --- 648,653 ---- > } > > + free(obj_name); > + > return TCL_ERROR; > } > *************** > *** 2018,2025 **** > case TYPE_CODE_ARRAY: > { > ! char number[16]; > *obj = Tcl_NewStringObj (NULL, 0); > ! sprintf (number, "%d", var->num_children); > Tcl_AppendStringsToObj (*obj, "[", number, "]", NULL); > } > break; > --- 2020,2028 ---- > case TYPE_CODE_ARRAY: > { > ! char *number; > *obj = Tcl_NewStringObj (NULL, 0); > ! asprintf (&number, "%d", var->num_children); > Tcl_AppendStringsToObj (*obj, "[", number, "]", NULL); > + free(number); > } > break; > diff -C2 -r -b ../gdb_cvs/src/gdb/gdbtk/generic/gdbtk.c > src/gdb/gdbtk/generic/gdbtk.c > *** ../gdb_cvs/src/gdb/gdbtk/generic/gdbtk.c Thu Jul 6 12:04:47 2000 > --- src/gdb/gdbtk/generic/gdbtk.c Thu Oct 19 10:59:48 2000 > *************** > *** 197,201 **** > { > va_list args; > ! char buf[10000], *v[3], *merge, *priority; > > switch (level) > --- 197,201 ---- > { > va_list args; > ! char *buf, *v[3], *merge, *priority; > > switch (level) > *************** > *** 216,230 **** > va_start (args, fmt); > > v[0] = "dbug"; > v[1] = priority; > v[2] = buf; > > - vsprintf (buf, fmt, args); > - va_end (args); > - > merge = Tcl_Merge (3, v); > if (Tcl_Eval (gdbtk_interp, merge) != TCL_OK) > Tcl_BackgroundError (gdbtk_interp); > Tcl_Free (merge); > } > > --- 216,232 ---- > va_start (args, fmt); > > + > + vasprintf (&buf, fmt, args); > + va_end (args); > + > v[0] = "dbug"; > v[1] = priority; > v[2] = buf; > > merge = Tcl_Merge (3, v); > if (Tcl_Eval (gdbtk_interp, merge) != TCL_OK) > Tcl_BackgroundError (gdbtk_interp); > Tcl_Free (merge); > + free(buf); > } > > *************** > *** 359,363 **** > struct cleanup *old_chain; > int found_main; > ! char s[5]; > Tcl_Obj *auto_path_elem, *auto_path_name; > > --- 361,365 ---- > struct cleanup *old_chain; > int found_main; > ! char *s; > Tcl_Obj *auto_path_elem, *auto_path_name; > > *************** > *** 389,394 **** > /* Set up some globals used by gdb to pass info to gdbtk > for start up options and the like */ > ! sprintf (s, "%d", inhibit_gdbinit); > Tcl_SetVar2 (gdbtk_interp, "GDBStartup", "inhibit_prefs", s, > TCL_GLOBAL_ONLY); > /* Note: Tcl_SetVar2() treats the value as read-only (making a > copy). Unfortunatly it does not mark the parameter as > --- 391,398 ---- > /* Set up some globals used by gdb to pass info to gdbtk > for start up options and the like */ > ! asprintf (&s, "%d", inhibit_gdbinit); > Tcl_SetVar2 (gdbtk_interp, "GDBStartup", "inhibit_prefs", s, > TCL_GLOBAL_ONLY); > + free(s); > + > /* Note: Tcl_SetVar2() treats the value as read-only (making a > copy). Unfortunatly it does not mark the parameter as