IAnjutaDebuggerWatch* gdb_watch_parse (const GDBMIValue *mi_results) { IAnjutaDebuggerWatch *watch; const GDBMIValue *value = NULL; if (mi_results) value = gdbmi_value_hash_lookup (mi_results, "value"); if ((mi_results == NULL) || (value == NULL)) { watch = g_new0 (IAnjutaDebuggerWatch, 1); watch->value = "?"; } else { gchar *pos; gchar *full_output; /* Concat the answers of gdb */ full_output = (char *)gdbmi_value_literal_get (value); pos = full_output; watch = g_new0 (IAnjutaDebuggerWatch, 1); parse_parent (watch, &pos); } return watch; }
static gchar * evaluate_gdb_variable_object_expression (GSwatGdbVariableObject *self, GError **error) { gchar *command; gulong token; GSwatGdbMIRecord *result; const GDBMIValue *value; gchar *value_string; command = g_strdup_printf ("-var-evaluate-expression %s", self->priv->gdb_name); token = gswat_gdb_debugger_send_mi_command (self->priv->debugger, command, NULL, NULL); g_free (command); result = gswat_gdb_debugger_get_mi_result_record (self->priv->debugger, token); if (!result) { /* An IO error has occurred */ return g_strdup ("Error retrieving value!");; } if (result && result->val) { value = gdbmi_value_hash_lookup (result->val, "value"); } if (value) { value_string = g_strdup (gdbmi_value_literal_get (value)); } else { g_warning ("Unexpected failure when retrieving variable value"); value_string = g_strdup ("Error retrieving value!"); g_set_error (error, GSWAT_VARIABLE_OBJECT_ERROR, GSWAT_VARIABLE_OBJECT_ERROR_GET_VALUE_FAILED, "Failed to retrieve the variable object's " "expresion value (%s)", self->priv->expression); } gswat_gdb_debugger_free_mi_record (result); return value_string; }
static gint count_gdb_variable_object_children (GSwatGdbVariableObject *self) { gchar *command; gulong token; GSwatGdbMIRecord *result; const GDBMIValue *numchild_val; gint child_count; /* find out if this expression has any children */ command = g_strdup_printf ("-var-info-num-children %s", self->priv->gdb_name); token = gswat_gdb_debugger_send_mi_command (self->priv->debugger, command, NULL, NULL); g_free (command); result=gswat_gdb_debugger_get_mi_result_record (self->priv->debugger, token); if (!result) { /* An IO error has occurred */ return 0; } numchild_val=gdbmi_value_hash_lookup (result->val, "numchild"); if (numchild_val) { const char *child_count_str; child_count_str = gdbmi_value_literal_get (numchild_val); child_count = (gint)strtoul (child_count_str, NULL, 10); } else { child_count = 0; } gswat_gdb_debugger_free_mi_record (result); return child_count; }
static void handle_changelist (GSwatGdbDebugger *gdb_debugger, const GSwatGdbMIRecord *record) { GList *all_variables, *all_variables_copy; int i, changed_count; GList *tmp; const GDBMIValue *val; const GDBMIValue *changelist_val; all_variables = g_object_get_data (G_OBJECT (gdb_debugger), "all-gswat-gdb-variable-objects"); all_variables_copy = g_list_copy (all_variables); g_list_foreach (all_variables_copy, (GFunc)g_object_ref, NULL); val = record->val; changelist_val = gdbmi_value_hash_lookup (val, "changelist"); changed_count = gdbmi_value_get_size (changelist_val); for (i=0; i<changed_count; i++) { const GDBMIValue *change_val; const char *variable_gdb_name; GSwatGdbVariableObject *variable_object; gboolean found = FALSE; gboolean child_count_changed = FALSE; gboolean type_changed = FALSE; change_val = gdbmi_value_list_get_nth (changelist_val, i); val = gdbmi_value_hash_lookup (change_val, "name"); variable_gdb_name = gdbmi_value_literal_get (val); for (tmp=all_variables_copy; tmp!=NULL; tmp=tmp->next) { char *gdb_name; variable_object = tmp->data; if (!variable_object->priv->gdb_name) { continue; } gdb_name = variable_object->priv->gdb_name; if (strcmp (gdb_name, variable_gdb_name)==0) { found = TRUE; break; } } if (!found) { g_warning ("gswat_gdb_variable_object_handle_changelist: got " "an unexpected change list entry"); continue; } val = gdbmi_value_hash_lookup (change_val, "in_scope"); if (strcmp (gdbmi_value_literal_get (val), "true") != 0) { delete_gdb_variable_object (variable_object); continue; } /* refering to gdb's varobj.c, then in the case * where a varobj can be evaluated in any * frame and its evaluated type changes, it * and its children are deleted and a new * root varobj with the same name is created * (for our purposes that means just the children * have been deleted) */ val = gdbmi_value_hash_lookup (change_val, "new_type"); if (val) { if (variable_object->priv->children) { for (tmp=variable_object->priv->children;tmp!=NULL;tmp=tmp->next) { delete_gdb_variable_object (tmp->data); } g_list_free (variable_object->priv->children); variable_object->priv->children = NULL; } type_changed = TRUE; } val = gdbmi_value_hash_lookup (change_val, "new_num_children"); if (val) { const gchar *child_count_str; child_count_str = gdbmi_value_literal_get (val); variable_object->priv->child_count = (gint)strtoul (child_count_str, NULL, 10); child_count_changed = TRUE; } else { if (type_changed) { variable_object->priv->child_count = -1; child_count_changed = TRUE; } } g_free (variable_object->priv->cached_value); val = gdbmi_value_hash_lookup (change_val, "value"); if (val) { const char *new_value; new_value = gdbmi_value_literal_get (val); variable_object->priv->cached_value=g_strdup (new_value); } else { variable_object->priv->cached_value = evaluate_gdb_variable_object_expression (variable_object, NULL); } /* #warning FIXME this workaround probably needs to be put * in more places */ if (!GSWAT_GDB_DEBUGGER_CAN_INSPECT_NULL_VAROBJS) { if (strcmp (variable_object->priv->cached_value, "0x0")==0) { variable_object->priv->child_count = 0; child_count_changed = TRUE; } else { variable_object->priv->child_count = -1; child_count_changed = TRUE; } } if (child_count_changed) { g_object_notify (G_OBJECT (variable_object), "child-count"); } g_object_notify (G_OBJECT (variable_object), "value"); } /* Mark all variable objects as up to date * and remove our temporary reference */ for (tmp=all_variables_copy; tmp!=NULL; tmp=tmp->next) { GSwatGdbVariableObject *variable_object; variable_object = tmp->data; variable_object->priv->gdb_interrupt_count = gswat_gdb_debugger_get_interrupt_count (variable_object->priv->debugger); g_object_unref (variable_object); } g_list_free (all_variables_copy); }
static GList * gswat_gdb_variable_object_get_children (GSwatVariableObject *object) { GSwatGdbVariableObject *self; GList *tmp; gchar *command; gulong token; GSwatGdbMIRecord *result; const GDBMIValue *children_val, *child_val; int n; GSwatGdbVariableObject *variable_object; g_return_val_if_fail (GSWAT_IS_GDB_VARIABLE_OBJECT (object), NULL); self = GSWAT_GDB_VARIABLE_OBJECT (object); if (!validate_variable_object (self)) { return NULL; } if (self->priv->children && self->priv->children_consistent) { g_list_foreach (self->priv->children, (GFunc)g_object_ref, NULL); return g_list_copy (self->priv->children); } /* --simple-values means print the name and value of * simple types, but omit the value for complex * types. Below we cache the number of * child->children as 0 if we get a value, else we * mark the number un-dermined (-1) */ command=g_strdup_printf ("-var-list-children --simple-values %s", self->priv->gdb_name); token = gswat_gdb_debugger_send_mi_command (self->priv->debugger, command, NULL, NULL); g_free (command); result = gswat_gdb_debugger_get_mi_result_record (self->priv->debugger, token); if (!result) { /* An IO error has occurred */ return NULL; } children_val = gdbmi_value_hash_lookup (result->val, "children"); n=0; while ( (child_val = gdbmi_value_list_get_nth (children_val, n))) { gboolean child_already_exists = FALSE; const GDBMIValue *name_val, *expression_val, *value_val; const GDBMIValue *numchild_val; const gchar *name_str, *expression_str, *child_value_str; const gchar *numchild_str; gint child_count; /* FIXME - gdb automatically creates variable objects * the first time you list children, but the docs * arn't clear about the frame number or expression * that are used. * * It looks like the expression is just the name * of the member (i.e. not a valid expression * in the scope of the parent expression) * * I need to find out about the frame number */ name_val = gdbmi_value_hash_lookup (child_val, "name"); name_str = gdbmi_value_literal_get (name_val); for (tmp=self->priv->children; tmp!=NULL; tmp=tmp->next) { variable_object = tmp->data; if (strcmp (variable_object->priv->gdb_name, name_str) == 0) { child_already_exists = TRUE; } } if (child_already_exists) { n++; continue; } expression_val = gdbmi_value_hash_lookup (child_val, "exp"); expression_str = gdbmi_value_literal_get (expression_val); /* complex types wont have a value */ value_val = gdbmi_value_hash_lookup (child_val, "value"); child_value_str=NULL; if (value_val) { child_value_str = gdbmi_value_literal_get (value_val); child_count = 0; } else { child_count = -1; } numchild_val = gdbmi_value_hash_lookup (child_val, "numchild"); numchild_str = NULL; if (numchild_val) { numchild_str = gdbmi_value_literal_get (numchild_val); child_count = (gint)strtoul (numchild_str, NULL, 10); } /* Note this function also adds the wrapped child to * the parents list of children */ variable_object = wrap_child_gdb_variable_object (self->priv->debugger, self, /* parent */ name_str, expression_str, child_value_str, self->priv->frame, child_count); n++; } self->priv->children_consistent = TRUE; gswat_gdb_debugger_free_mi_record (result); return g_list_copy (self->priv->children); }
static gboolean create_gdb_variable_object (GSwatGdbVariableObject *self) { gchar *command; gulong token; GSwatGdbMIRecord *result; const GDBMIValue *numchild_val; if (self->priv->frame == GSWAT_VARIABLE_OBJECT_ANY_FRAME) { command = g_strdup_printf ("-var-create v%d @ %s", global_variable_object_index, self->priv->expression); } else if (self->priv->frame == GSWAT_VARIABLE_OBJECT_CURRENT_NOW_FRAME) { command = g_strdup_printf ("-var-create v%d * %s", global_variable_object_index, self->priv->expression); } else { g_warning ("create_gdb_variable_object: doesn't currently " "support arbitrary frame choice"); } token = gswat_gdb_debugger_send_mi_command (self->priv->debugger, command, NULL, NULL); g_free (command); /* FIXME - make sure we can cope with junk expressions */ result=gswat_gdb_debugger_get_mi_result_record (self->priv->debugger, token); if (!result) { /* An IO error has occurred */ return FALSE; } numchild_val=gdbmi_value_hash_lookup (result->val, "numchild"); if (numchild_val) { const char *child_count_str; child_count_str = gdbmi_value_literal_get (numchild_val); self->priv->child_count = (gint)strtoul (child_count_str, NULL, 10); } else { /* Mark the child_count as "unknown" */ self->priv->child_count = -1; } gswat_gdb_debugger_free_mi_record (result); self->priv->gdb_name = g_strdup_printf ("v%d", global_variable_object_index); global_variable_object_index++; return TRUE; }