GDB (API)
|
00001 /* Variable user interface layer for GDB, the GNU debugger. 00002 Copyright (C) 1999, 2000, 2001, 2002, 2008, 2010 00003 Free Software Foundation, Inc. 00004 00005 This file is part of GDB. 00006 00007 This program is free software; you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License as published by 00009 the Free Software Foundation; either version 2 of the License, or 00010 (at your option) any later version. 00011 00012 This program is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with this program; if not, write to the Free Software 00019 Foundation, Inc., 51 Franklin Street, Fifth Floor, 00020 Boston, MA 02110-1301, USA. */ 00021 00022 #include "defs.h" 00023 #include "value.h" 00024 #include "gdb_string.h" 00025 #include "varobj.h" 00026 #include "exceptions.h" 00027 00028 #include <tcl.h> 00029 #include "gdbtk.h" 00030 #include "gdbtk-cmds.h" 00031 #include "gdbtk-wrapper.h" 00032 00033 /* 00034 * Public functions defined in this file 00035 */ 00036 00037 int gdb_variable_init (Tcl_Interp *); 00038 00039 /* 00040 * Private functions defined in this file 00041 */ 00042 00043 /* Entries into this file */ 00044 00045 static int gdb_variable_command (ClientData, Tcl_Interp *, int, 00046 Tcl_Obj * CONST[]); 00047 00048 static int variable_obj_command (ClientData, Tcl_Interp *, int, 00049 Tcl_Obj * CONST[]); 00050 00051 /* Variable object subcommands */ 00052 00053 static int variable_create (Tcl_Interp *, int, Tcl_Obj * CONST[]); 00054 00055 static void variable_delete (Tcl_Interp *, struct varobj *, int); 00056 00057 static Tcl_Obj *variable_children (Tcl_Interp *, struct varobj *); 00058 00059 static int variable_format (Tcl_Interp *, int, Tcl_Obj * CONST[], 00060 struct varobj *); 00061 00062 static int variable_type (Tcl_Interp *, int, Tcl_Obj * CONST[], 00063 struct varobj *); 00064 00065 static int variable_value (Tcl_Interp *, int, Tcl_Obj * CONST[], 00066 struct varobj *); 00067 00068 static Tcl_Obj *variable_update (Tcl_Interp * interp, struct varobj **var); 00069 00070 /* Helper functions for the above subcommands. */ 00071 00072 static void install_variable (Tcl_Interp *, char *); 00073 00074 static void uninstall_variable (Tcl_Interp *, char *); 00075 00076 /* String representations of gdb's format codes */ 00077 static char *format_string[] = 00078 {"natural", "binary", "decimal", "hexadecimal", "octal"}; 00079 00080 00081 /* Initialize the variable code. This function should be called once 00082 to install and initialize the variable code into the interpreter. */ 00083 int 00084 gdb_variable_init (Tcl_Interp *interp) 00085 { 00086 Tcl_Command result; 00087 static int initialized = 0; 00088 00089 if (!initialized) 00090 { 00091 result = Tcl_CreateObjCommand (interp, "gdb_variable", gdbtk_call_wrapper, 00092 (ClientData) gdb_variable_command, NULL); 00093 if (result == NULL) 00094 return TCL_ERROR; 00095 00096 initialized = 1; 00097 } 00098 00099 return TCL_OK; 00100 } 00101 00102 /* This function defines the "gdb_variable" command which is used to 00103 create variable objects. Its syntax includes: 00104 00105 gdb_variable create 00106 gdb_variable create NAME 00107 gdb_variable create -expr EXPR 00108 gdb_variable create -frame FRAME 00109 (it will also include permutations of the above options) 00110 00111 NAME = name of object to create. If no NAME, then automatically create 00112 a name 00113 EXPR = the gdb expression for which to create a variable. This will 00114 be the most common usage. 00115 FRAME = the frame defining the scope of the variable. 00116 */ 00117 static int 00118 gdb_variable_command (ClientData clientData, Tcl_Interp *interp, 00119 int objc, Tcl_Obj *CONST objv[]) 00120 { 00121 static const char *commands[] = 00122 {"create", "list", NULL}; 00123 enum commands_enum 00124 { 00125 VARIABLE_CREATE, VARIABLE_LIST 00126 }; 00127 int index, result; 00128 00129 if (objc < 2) 00130 { 00131 Tcl_WrongNumArgs (interp, 1, objv, "option ?arg...?"); 00132 return TCL_ERROR; 00133 } 00134 00135 if (Tcl_GetIndexFromObj (interp, objv[1], commands, "options", 0, 00136 &index) != TCL_OK) 00137 { 00138 return TCL_ERROR; 00139 } 00140 00141 switch ((enum commands_enum) index) 00142 { 00143 case VARIABLE_CREATE: 00144 result = variable_create (interp, objc - 2, objv + 2); 00145 break; 00146 00147 default: 00148 return TCL_ERROR; 00149 } 00150 00151 return result; 00152 } 00153 00154 /* This function implements the actual object command for each 00155 variable object that is created (and each of its children). 00156 00157 Currently the following commands are implemented: 00158 - delete delete this object and its children 00159 - update update the variable and its children (root vars only) 00160 - numChildren how many children does this object have 00161 - children create the children and return a list of their objects 00162 - name print out the name of this variable 00163 - format query/set the display format of this variable 00164 - type get the type of this variable 00165 - value get/set the value of this variable 00166 - editable is this variable editable? 00167 */ 00168 static int 00169 variable_obj_command (ClientData clientData, Tcl_Interp *interp, 00170 int objc, Tcl_Obj *CONST objv[]) 00171 { 00172 enum commands_enum 00173 { 00174 VARIABLE_DELETE, 00175 VARIABLE_NUM_CHILDREN, 00176 VARIABLE_CHILDREN, 00177 VARIABLE_FORMAT, 00178 VARIABLE_TYPE, 00179 VARIABLE_VALUE, 00180 VARIABLE_NAME, 00181 VARIABLE_EDITABLE, 00182 VARIABLE_UPDATE 00183 }; 00184 static const char *commands[] = 00185 { 00186 "delete", 00187 "numChildren", 00188 "children", 00189 "format", 00190 "type", 00191 "value", 00192 "name", 00193 "editable", 00194 "update", 00195 NULL 00196 }; 00197 struct varobj *var; 00198 char *varobj_name; 00199 int index, result; 00200 00201 /* Get the current handle for this variable token (name). */ 00202 varobj_name = Tcl_GetStringFromObj (objv[0], NULL); 00203 if (varobj_name == NULL) 00204 return TCL_ERROR; 00205 var = varobj_get_handle (varobj_name); 00206 00207 00208 if (objc < 2) 00209 { 00210 Tcl_WrongNumArgs (interp, 1, objv, "option ?arg...?"); 00211 return TCL_ERROR; 00212 } 00213 00214 if (Tcl_GetIndexFromObj (interp, objv[1], commands, "options", 0, 00215 &index) != TCL_OK) 00216 return TCL_ERROR; 00217 00218 result = TCL_OK; 00219 switch ((enum commands_enum) index) 00220 { 00221 case VARIABLE_DELETE: 00222 if (objc > 2) 00223 { 00224 int len; 00225 char *s = Tcl_GetStringFromObj (objv[2], &len); 00226 if (*s == 'c' && strncmp (s, "children", len) == 0) 00227 { 00228 variable_delete (interp, var, 1 /* only children */ ); 00229 break; 00230 } 00231 } 00232 variable_delete (interp, var, 0 /* var and children */ ); 00233 break; 00234 00235 case VARIABLE_NUM_CHILDREN: 00236 Tcl_SetObjResult (interp, Tcl_NewIntObj (varobj_get_num_children (var))); 00237 break; 00238 00239 case VARIABLE_CHILDREN: 00240 { 00241 Tcl_Obj *children = variable_children (interp, var); 00242 Tcl_SetObjResult (interp, children); 00243 } 00244 break; 00245 00246 case VARIABLE_FORMAT: 00247 result = variable_format (interp, objc, objv, var); 00248 break; 00249 00250 case VARIABLE_TYPE: 00251 result = variable_type (interp, objc, objv, var); 00252 break; 00253 00254 case VARIABLE_VALUE: 00255 result = variable_value (interp, objc, objv, var); 00256 break; 00257 00258 case VARIABLE_NAME: 00259 { 00260 char *name = varobj_get_expression (var); 00261 Tcl_SetObjResult (interp, Tcl_NewStringObj (name, -1)); 00262 xfree (name); 00263 } 00264 break; 00265 00266 case VARIABLE_EDITABLE: 00267 Tcl_SetObjResult (interp, 00268 Tcl_NewIntObj (varobj_get_attributes (var) & 0x00000001 /* Editable? */ )); 00269 break; 00270 00271 case VARIABLE_UPDATE: 00272 /* Only root variables can be updated */ 00273 { 00274 Tcl_Obj *obj = variable_update (interp, &var); 00275 Tcl_SetObjResult (interp, obj); 00276 } 00277 break; 00278 00279 default: 00280 return TCL_ERROR; 00281 } 00282 00283 return result; 00284 } 00285 00286 /* 00287 * Variable object construction/destruction 00288 */ 00289 00290 /* This function is responsible for processing the user's specifications 00291 and constructing a variable object. */ 00292 static int 00293 variable_create (Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) 00294 { 00295 enum create_opts 00296 { 00297 CREATE_EXPR, CREATE_FRAME 00298 }; 00299 static const char *create_options[] = 00300 {"-expr", "-frame", NULL}; 00301 struct varobj *var; 00302 char *name; 00303 char *obj_name; 00304 int index; 00305 CORE_ADDR frame = (CORE_ADDR) -1; 00306 int how_specified = USE_SELECTED_FRAME; 00307 00308 /* REMINDER: This command may be invoked in the following ways: 00309 gdb_variable create [NAME] [-expr EXPR] [-frame FRAME] 00310 00311 NAME = name of object to create. If no NAME, then automatically create 00312 a name 00313 EXPR = the gdb expression for which to create a variable. This will 00314 be the most common usage. 00315 FRAME = the address of the frame defining the variable's scope 00316 */ 00317 name = NULL; 00318 if (objc) 00319 name = Tcl_GetStringFromObj (objv[0], NULL); 00320 if (name == NULL || *name == '-') 00321 { 00322 /* generate a name for this object */ 00323 obj_name = varobj_gen_name (); 00324 } 00325 else 00326 { 00327 /* specified name for object */ 00328 obj_name = xstrdup (name); 00329 objv++; 00330 objc--; 00331 } 00332 00333 /* Run through all the possible options for this command */ 00334 name = NULL; 00335 while (objc > 0) 00336 { 00337 if (Tcl_GetIndexFromObj (interp, objv[0], create_options, "options", 00338 0, &index) != TCL_OK) 00339 { 00340 xfree (obj_name); 00341 result_ptr->flags |= GDBTK_IN_TCL_RESULT; 00342 return TCL_ERROR; 00343 } 00344 00345 switch ((enum create_opts) index) 00346 { 00347 case CREATE_EXPR: 00348 name = Tcl_GetStringFromObj (objv[1], NULL); 00349 objc--; 00350 objv++; 00351 break; 00352 00353 case CREATE_FRAME: 00354 { 00355 char *str; 00356 str = Tcl_GetStringFromObj (objv[1], NULL); 00357 frame = string_to_core_addr (str); 00358 how_specified = USE_SPECIFIED_FRAME; 00359 objc--; 00360 objv++; 00361 } 00362 break; 00363 00364 default: 00365 break; 00366 } 00367 00368 objc--; 00369 objv++; 00370 } 00371 00372 /* Create the variable */ 00373 var = varobj_create (obj_name, name, frame, how_specified); 00374 00375 if (var != NULL) 00376 { 00377 /* Install a command into the interpreter that represents this 00378 object */ 00379 install_variable (interp, obj_name); 00380 Tcl_SetObjResult (interp, Tcl_NewStringObj (obj_name, -1)); 00381 result_ptr->flags |= GDBTK_IN_TCL_RESULT; 00382 00383 xfree (obj_name); 00384 return TCL_OK; 00385 } 00386 00387 xfree (obj_name); 00388 return TCL_ERROR; 00389 } 00390 00391 /* Delete the variable object VAR and its children */ 00392 /* If only_children_p, Delete only the children associated with the object. */ 00393 static void 00394 variable_delete (Tcl_Interp *interp, struct varobj *var, 00395 int only_children_p) 00396 { 00397 char **dellist; 00398 char **vc; 00399 00400 varobj_delete (var, &dellist, only_children_p); 00401 00402 vc = dellist; 00403 while (*vc != NULL) 00404 { 00405 uninstall_variable (interp, *vc); 00406 xfree (*vc); 00407 vc++; 00408 } 00409 00410 xfree (dellist); 00411 } 00412 00413 /* Return a list of all the children of VAR, creating them if necessary. */ 00414 static Tcl_Obj * 00415 variable_children (Tcl_Interp *interp, struct varobj *var) 00416 { 00417 Tcl_Obj *list; 00418 VEC(varobj_p) *children; 00419 struct varobj *child; 00420 char *childname; 00421 int ix, from, to; 00422 00423 list = Tcl_NewListObj (0, NULL); 00424 00425 from = -1; 00426 to = -1; 00427 00428 children = varobj_list_children (var, &from, &to); 00429 00430 for (ix = from; ix < to && VEC_iterate (varobj_p, children, ix, child); ++ix) 00431 { 00432 childname = varobj_get_objname (child); 00433 /* Add child to result list and install the Tcl command for it. */ 00434 Tcl_ListObjAppendElement (NULL, list, 00435 Tcl_NewStringObj (childname, -1)); 00436 install_variable (interp, childname); 00437 } 00438 00439 return list; 00440 } 00441 00442 /* Update the values for a variable and its children. */ 00443 /* NOTE: Only root variables can be updated... */ 00444 00445 static Tcl_Obj * 00446 variable_update (Tcl_Interp *interp, struct varobj **var) 00447 { 00448 int i; 00449 Tcl_Obj *changed; 00450 VEC (varobj_update_result) *changes; 00451 varobj_update_result *r; 00452 00453 if (GDB_varobj_update (var, 1, &changes) != GDB_OK) 00454 return Tcl_NewStringObj ("-1", -1); 00455 00456 changed = Tcl_NewListObj (0, NULL); 00457 for (i = 0; VEC_iterate (varobj_update_result, changes, i, r); ++i) 00458 { 00459 switch (r->status) 00460 { 00461 case VAROBJ_IN_SCOPE: 00462 { 00463 Tcl_Obj *var 00464 = Tcl_NewStringObj (varobj_get_objname (r->varobj), -1); 00465 Tcl_ListObjAppendElement (NULL, changed, var); 00466 } 00467 break; 00468 00469 case VAROBJ_NOT_IN_SCOPE: 00470 case VAROBJ_INVALID: 00471 /* These need to be (re-)implemented in the UI */ 00472 break; 00473 } 00474 } 00475 00476 return changed; 00477 } 00478 00479 /* This implements the format object command allowing 00480 the querying or setting of the object's display format. */ 00481 static int 00482 variable_format (Tcl_Interp *interp, int objc, 00483 Tcl_Obj *CONST objv[], struct varobj *var) 00484 { 00485 if (objc > 2) 00486 { 00487 /* Set the format of VAR to given format */ 00488 int len; 00489 char *fmt = Tcl_GetStringFromObj (objv[2], &len); 00490 if (strncmp (fmt, "natural", len) == 0) 00491 varobj_set_display_format (var, FORMAT_NATURAL); 00492 else if (strncmp (fmt, "binary", len) == 0) 00493 varobj_set_display_format (var, FORMAT_BINARY); 00494 else if (strncmp (fmt, "decimal", len) == 0) 00495 varobj_set_display_format (var, FORMAT_DECIMAL); 00496 else if (strncmp (fmt, "hexadecimal", len) == 0) 00497 varobj_set_display_format (var, FORMAT_HEXADECIMAL); 00498 else if (strncmp (fmt, "octal", len) == 0) 00499 varobj_set_display_format (var, FORMAT_OCTAL); 00500 else 00501 { 00502 gdbtk_set_result (interp, "unknown display format \"", 00503 fmt, "\": must be: \"natural\", \"binary\"" 00504 ", \"decimal\", \"hexadecimal\", or \"octal\""); 00505 return TCL_ERROR; 00506 } 00507 } 00508 else 00509 { 00510 /* Report the current format */ 00511 Tcl_Obj *fmt; 00512 00513 /* FIXME: Use varobj_format_string[] instead */ 00514 fmt = Tcl_NewStringObj ( 00515 format_string[(int) varobj_get_display_format (var)], -1); 00516 Tcl_SetObjResult (interp, fmt); 00517 } 00518 00519 return TCL_OK; 00520 } 00521 00522 /* This function implements the type object command, which returns the type of a 00523 variable in the interpreter (or an error). */ 00524 static int 00525 variable_type (Tcl_Interp *interp, int objc, 00526 Tcl_Obj *CONST objv[], struct varobj *var) 00527 { 00528 const char *first; 00529 const char *last; 00530 char *string; 00531 Tcl_RegExp regexp; 00532 00533 /* For the "fake" variables, do not return a type. 00534 Their type is NULL anyway */ 00535 /* FIXME: varobj_get_type() calls type_print(), so we may have to wrap 00536 its call here and return TCL_ERROR in the case it errors out */ 00537 if ((string = varobj_get_type (var)) == NULL) 00538 { 00539 Tcl_ResetResult (interp); 00540 return TCL_OK; 00541 } 00542 00543 first = string; 00544 00545 /* gdb will print things out like "struct {...}" for anonymous structs. 00546 In gui-land, we don't want the {...}, so we strip it here. */ 00547 regexp = Tcl_RegExpCompile (interp, "{...}"); 00548 if (Tcl_RegExpExec (interp, regexp, string, first)) 00549 { 00550 /* We have an anonymous struct/union/class/enum */ 00551 Tcl_RegExpRange (regexp, 0, &first, &last); 00552 if (*(first - 1) == ' ') 00553 first--; 00554 string[first - string] = '\0'; 00555 } 00556 00557 Tcl_SetObjResult (interp, Tcl_NewStringObj (string, -1)); 00558 xfree (string); 00559 return TCL_OK; 00560 } 00561 00562 /* This function implements the value object command, which allows an object's 00563 value to be queried or set. */ 00564 static int 00565 variable_value (Tcl_Interp *interp, int objc, 00566 Tcl_Obj *CONST objv[], struct varobj *var) 00567 { 00568 char *r; 00569 00570 /* If we're setting the value of the variable, objv[2] will contain the 00571 variable's new value. */ 00572 if (objc > 2) 00573 { 00574 /* FIXME: Do we need to test if val->error is set here? 00575 If so, make it an attribute. */ 00576 if (varobj_get_attributes (var) & 0x00000001 /* Editable? */ ) 00577 { 00578 char *s; 00579 int ok = 0; 00580 struct gdb_exception e; 00581 00582 s = Tcl_GetStringFromObj (objv[2], NULL); 00583 TRY_CATCH (e, RETURN_MASK_ERROR) 00584 { 00585 ok = varobj_set_value (var, s); 00586 } 00587 00588 if (e.reason < 0 || !ok) 00589 { 00590 gdbtk_set_result (interp, "Could not assign expression to variable object"); 00591 return TCL_ERROR; 00592 } 00593 } 00594 00595 Tcl_ResetResult (interp); 00596 return TCL_OK; 00597 } 00598 00599 r = varobj_get_value (var); 00600 00601 if (r == NULL) 00602 { 00603 gdbtk_set_result (interp, "Could not read variable object value after assignment"); 00604 return TCL_ERROR; 00605 } 00606 else 00607 { 00608 Tcl_SetObjResult (interp, Tcl_NewStringObj (r, -1)); 00609 xfree (r); 00610 return TCL_OK; 00611 } 00612 } 00613 00614 /* Helper functions for the above */ 00615 00616 /* Install the given variable VAR into the tcl interpreter with 00617 the object name NAME. */ 00618 static void 00619 install_variable (Tcl_Interp *interp, char *name) 00620 { 00621 Tcl_CreateObjCommand (interp, name, variable_obj_command, 00622 NULL, NULL); 00623 } 00624 00625 /* Unistall the object VAR in the tcl interpreter. */ 00626 static void 00627 uninstall_variable (Tcl_Interp *interp, char *varname) 00628 { 00629 Tcl_DeleteCommand (interp, varname); 00630 } 00631