struct ibuf *ibuf_init(void) { struct ibuf *s = (struct ibuf *) cgdb_malloc(sizeof (struct ibuf)); s->BLOCK_SIZE = 4096; s->cur_block_size = 1; s->cur_buf_pos = 0; s->buf = (char *) cgdb_malloc(sizeof (char) * (s->BLOCK_SIZE)); s->buf[s->cur_buf_pos] = '\0'; return s; }
/** * This is called when GDB has finished. * Its job is to add the type of QUIT command that is appropriate. * * \param tgdb * The tgdb context * * \param tgdb_will_quit * This will return as 1 if tgdb sent the TGDB_QUIT command. Otherwise 0. * * \return * 0 on success or -1 on error */ int Ctgdb::Get_quit_command (int *tgdb_will_quit) { pid_t pid = tgdb_client_get_debugger_pid (tcc); int status = 0; pid_t ret; struct tgdb_debugger_exit_status *tstatus; struct tgdb_response *response = (struct tgdb_response *) cgdb_malloc (sizeof (struct tgdb_response)); if (!tgdb_will_quit) return -1; *tgdb_will_quit = 0; tstatus = (struct tgdb_debugger_exit_status *) cgdb_malloc (sizeof (struct tgdb_debugger_exit_status)); ret = waitpid (pid, &status, WNOHANG); if (ret == -1) { Logger_write_pos( __FILE__, __LINE__, "waitpid error"); return -1; } else if (ret == 0) { /* This SIGCHLD wasn't for GDB */ return 0; } if ((WIFEXITED (status)) == 0) { /* Child did not exit normally */ tstatus->exit_status = -1; tstatus->return_value = 0; } else { tstatus->exit_status = 0; tstatus->return_value = WEXITSTATUS (status); } response->header = TGDB_QUIT; response->choice.quit.exit_status = tstatus; tgdb_types_append_command (command_list, response); *tgdb_will_quit = 1; return 0; }
static struct tgdb *initialize_tgdb_context(tgdb_callbacks callbacks) { struct tgdb *tgdb = (struct tgdb *) cgdb_malloc(sizeof (struct tgdb)); tgdb->c = 0; tgdb->parser = NULL; tgdb->control_c = 0; tgdb->debugger_stdout = -1; tgdb->debugger_stdin = -1; tgdb->inferior_stdout = -1; tgdb->inferior_stdin = -1; tgdb->pty_pair = NULL; tgdb->command_requests = new tgdb_request_ptr_list(); tgdb->is_gdb_ready_for_next_command = 1; tgdb->make_console_ready_callback = true; tgdb->has_sigchld_recv = 0; tgdb->callbacks = callbacks; return tgdb; }
struct scroller *scr_new(SWINDOW *win) { struct scroller *rv; rv = (struct scroller *)cgdb_malloc(sizeof(struct scroller)); rv->current.r = 0; rv->current.c = 0; rv->current.pos = 0; rv->in_scroll_mode = 0; rv->last_inferior_line = NULL; rv->last_inferior_attr = -1; rv->lines_to_display = 0; rv->win = win; rv->in_search_mode = 0; rv->last_hlregex = NULL; rv->hlregex = NULL; rv->search_r = 0; /* Start with a single (blank) line */ rv->lines = NULL; scroller_addline(rv, strdup(""), NULL, SCR_INPUT_DEBUGGER); rv->jump_back_mark.r = -1; rv->jump_back_mark.c = -1; memset(rv->marks, 0xff, sizeof(rv->marks)); return rv; }
static void tgdb_issue_request(struct tgdb *tgdb, enum tgdb_request_type type, bool priority) { tgdb_request_ptr request_ptr; request_ptr = (tgdb_request_ptr)cgdb_malloc(sizeof (struct tgdb_request)); request_ptr->header = type; tgdb_run_or_queue_request(tgdb, request_ptr, priority); }
struct state_machine *state_machine_initialize ( void ) { struct state_machine *sm = (struct state_machine * ) cgdb_malloc ( sizeof ( struct state_machine ) ); sm->tgdb_buffer = ibuf_init (); sm->tgdb_state = DATA; return sm; }
/* gdb_input: Handles user input to the GDB window. * ---------- * * key: Keystroke received. * * Return Value: 0 if internal key was used, * 1 if input to gdb or ... * -1 : Error resizing terminal -- terminal too small */ static int gdb_input(int key) { /* Handle special keys */ switch (key) { case CGDB_KEY_PPAGE: scr_up(gdb_win, get_gdb_height() - 1); break; case CGDB_KEY_NPAGE: scr_down(gdb_win, get_gdb_height() - 1); break; case CGDB_KEY_F11: scr_home(gdb_win); break; case CGDB_KEY_F12: scr_end(gdb_win); break; #if 0 /* I would like to add better support for control-l in the GDB * window, but this patch didn't make me happy enough to release it. * The problem is, when it clears the screen, it adds a lot of * whitespace in the buffer. If you hit page-up to look back in * the buffer, it's visible. This is really unacceptable. * * The approach I believe I would like to take with this, is to * have the GDB window behave more like the terminal. That is, * have GDB start at the top line, and move down as input * becomes available. Then, when you hit ctrl-l, you just move * the prompt to the top line. */ case CGDB_KEY_CTRL_L: { int height = get_gdb_height(), i; /* Allocate and print enough newlines to clear the gdb buffer. */ char *buf = (char *) cgdb_malloc(sizeof (char *) * height); for (i = 0; i < height - 1; ++i) { buf[i] = '\n'; } buf[i] = '\0'; if_print(buf); free(buf); /* Sneaky return 1 here. Basically, this allows tricks readline to think * that gdb did not handle the Ctrl-l. That way readline will also handle * it. Because readline uses TERM=dumb, that means that it will clear a * single line and put out the prompt. */ return 1; break; } #endif default: return 1; } if_draw(); return 0; }
void tgdb_request_complete(struct tgdb * tgdb, const char *line) { tgdb_request_ptr request_ptr; request_ptr = (tgdb_request_ptr)cgdb_malloc(sizeof (struct tgdb_request)); request_ptr->header = TGDB_REQUEST_COMPLETE; request_ptr->choice.complete.line = (const char *)cgdb_strdup(line); tgdb_run_or_queue_request(tgdb, request_ptr, false); }
void tgdb_request_current_location(struct tgdb * tgdb) { tgdb_request_ptr request_ptr; request_ptr = (tgdb_request_ptr)cgdb_malloc(sizeof (struct tgdb_request)); request_ptr->header = TGDB_REQUEST_INFO_FRAME; tgdb_run_or_queue_request(tgdb, request_ptr, true); }
void tgdb_request_inferiors_source_files(struct tgdb * tgdb) { tgdb_request_ptr request_ptr; request_ptr = (tgdb_request_ptr)cgdb_malloc(sizeof (struct tgdb_request)); request_ptr->header = TGDB_REQUEST_INFO_SOURCES; tgdb_run_or_queue_request(tgdb, request_ptr, false); }
/** * TGDB is going to quit. * * \param tgdb * The tgdb context * * \return * 0 on success or -1 on error */ int Ctgdb::Add_quit_command() { struct tgdb_debugger_exit_status *tstatus; struct tgdb_response *response; tstatus = (struct tgdb_debugger_exit_status *) cgdb_malloc (sizeof (struct tgdb_debugger_exit_status)); /* Child did not exit normally */ tstatus->exit_status = -1; tstatus->return_value = 0; response = (struct tgdb_response *) cgdb_malloc (sizeof (struct tgdb_response)); response->header = TGDB_QUIT; response->choice.quit.exit_status = tstatus; tgdb_types_append_command (command_list, response); return 0; }
void tgdb_request_disassemble_pc(struct tgdb *tgdb, int lines) { tgdb_request_ptr request_ptr; request_ptr = (tgdb_request_ptr)cgdb_malloc(sizeof (struct tgdb_request)); request_ptr->header = TGDB_REQUEST_DISASSEMBLE_PC; request_ptr->choice.disassemble.lines = lines; tgdb_run_or_queue_request(tgdb, request_ptr, false); }
/** * Create a tab completion context. * * \param matches * See tab_completion field documentation * * \param num_matches * See tab_completion field documentation * * \param max_length * See tab_completion field documentation * * \return * The next context, or NULL on error. */ static tab_completion_ptr tab_completion_create(char **matches, int num_matches, int max_length) { int i; tab_completion_ptr comptr; comptr = (tab_completion_ptr) cgdb_malloc(sizeof (struct tab_completion_ctx)); comptr->matches = cgdb_malloc(sizeof (char *) * (num_matches + 1)); for (i = 0; i <= num_matches; ++i) comptr->matches[i] = cgdb_strdup(matches[i]); comptr->num_matches = num_matches; comptr->max_length = max_length; comptr->total = 1; comptr->lines = 0; comptr->state = TAB_COMPLETION_START; return comptr; }
void tgdb_request_run_debugger_command(struct tgdb * tgdb, enum tgdb_command_type c) { tgdb_request_ptr request_ptr; request_ptr = (tgdb_request_ptr)cgdb_malloc(sizeof (struct tgdb_request)); request_ptr->header = TGDB_REQUEST_DEBUGGER_COMMAND; request_ptr->choice.debugger_command.c = c; tgdb_run_or_queue_request(tgdb, request_ptr, false); }
/** * Gets a list of source files that make up the program being debugged. * * This function does not actually do anything but put a command in the * queue to be run when libtgdb is ready. When the libtgdb runs the * command to get the inferior's source files, it will return 1 of 2 * things next time tgdb_recv is called. * * If the function succeeds the gui will get back TGDB_UPDATE_SOURCE_FILES * containing a list of all the source files. Otherwise the gui will get * back TGDB_SOURCES_DENIED. * * \param tgdb * An instance of the tgdb library to operate on. * * \return * Will return as a tgdb request command on success, otherwise NULL. */ tgdb_request_ptr Ctgdb::Request_inferiors_source_files() { tgdb_request_ptr request_ptr; request_ptr = (tgdb_request_ptr) cgdb_malloc (sizeof (struct tgdb_request)); if (!request_ptr) return NULL; request_ptr->header = TGDB_REQUEST_INFO_SOURCES; return request_ptr; }
void tgdb_request_run_console_command(struct tgdb *tgdb, const char *command) { tgdb_request_ptr request_ptr; request_ptr = (tgdb_request_ptr)cgdb_malloc(sizeof (struct tgdb_request)); request_ptr->header = TGDB_REQUEST_CONSOLE_COMMAND; request_ptr->choice.console_command.command = (const char *) cgdb_strdup(command); tgdb_run_or_queue_request(tgdb, request_ptr, false); }
void tgdb_request_disassemble_func(struct tgdb *tgdb, enum disassemble_func_type type) { tgdb_request_ptr request_ptr; request_ptr = (tgdb_request_ptr)cgdb_malloc(sizeof (struct tgdb_request)); request_ptr->header = TGDB_REQUEST_DISASSEMBLE_FUNC; request_ptr->choice.disassemble_func.raw = (type == DISASSEMBLE_FUNC_RAW_INSTRUCTIONS); request_ptr->choice.disassemble_func.source = (type == DISASSEMBLE_FUNC_SOURCE_LINES); tgdb_run_or_queue_request(tgdb, request_ptr, false); }
/** * This will ask the debugger for it's current file and line number. * It will return to the caller a tgdb_response with the * response->update_source_files set. This is the same response you * will get when TGDB asynchronously sends the update_file_postition. * * \param tgdb * An instance of the tgdb library to operate on. * * \param on_starup * This variable can be set to 1 if the front end wants to probe GDB * for the initial file and location of the program being debugged. * However, each initial time after that, this variable should be * set to 0. * * \return * Will return as a tgdb request command on success, otherwise NULL. */ tgdb_request_ptr Ctgdb::Request_current_location(int on_startup) { tgdb_request_ptr request_ptr; request_ptr = (tgdb_request_ptr) cgdb_malloc (sizeof (struct tgdb_request)); if (!request_ptr) return NULL; request_ptr->header = TGDB_REQUEST_CURRENT_LOCATION; request_ptr->choice.current_location.on_startup = on_startup; return request_ptr; }
/** * This tells libtgdb to run a command through the debugger. * * \param tgdb * An instance of the tgdb library to operate on. * * \param c * This is the command that libtgdb should run through the debugger. * * @return * Will return as a tgdb request command on success, otherwise NULL. */ tgdb_request_ptr Ctgdb::Request_run_debugger_command(enum tgdb_command_type c) { tgdb_request_ptr request_ptr; request_ptr = (tgdb_request_ptr) cgdb_malloc (sizeof (struct tgdb_request)); if (!request_ptr) return NULL; request_ptr->header = TGDB_REQUEST_DEBUGGER_COMMAND; request_ptr->choice.debugger_command.c = c; return request_ptr; }
void highlight(struct list_node *node) { if ( node->language == TOKENIZER_LANGUAGE_UNKNOWN ) { /* Just copy the lines from the original buffer if no highlighting * is possible */ int i; node->buf.length = node->orig_buf.length; node->buf.max_width = node->orig_buf.max_width; node->buf.tlines = cgdb_malloc ( sizeof ( char * ) * node->orig_buf.length ); for ( i = 0; i < node->orig_buf.length; i++ ) node->buf.tlines[i] = cgdb_strdup ( node->orig_buf.tlines[i] ); } else highlight_node ( node ); }
struct filedlg *filedlg_new(int pos_r, int pos_c, int height, int width) { struct filedlg *fd; /* Allocate a new structure */ fd = (struct filedlg *)cgdb_malloc(sizeof(struct filedlg)); /* Initialize the structure */ fd->win = swin_newwin(height, width, pos_r, pos_c); /* Initialize the buffer */ fd->buf = (struct file_buffer *)cgdb_malloc(sizeof(struct file_buffer)); fd->G_line_number = ibuf_init(); fd->last_hlregex = NULL; fd->hlregex = NULL; fd->buf->files = NULL; fd->buf->max_width = 0; fd->buf->sel_line = 0; fd->buf->sel_col = 0; fd->buf->sel_rline = 0; return fd; }
/** * Used to get all of the possible tab completion options for LINE. * * \param tgdb * An instance of the tgdb library to operate on. * * \param line * The line to tab complete. * * \return * Will return as a tgdb request command on success, otherwise NULL. */ tgdb_request_ptr Ctgdb::Request_complete(const char *line) { tgdb_request_ptr request_ptr; request_ptr = (tgdb_request_ptr) cgdb_malloc (sizeof (struct tgdb_request)); if (!request_ptr) return NULL; request_ptr->header = TGDB_REQUEST_COMPLETE; request_ptr->choice.complete.line = (const char *) cgdb_strdup (line); return request_ptr; }
void tgdb_request_modify_breakpoint(struct tgdb *tgdb, const char *file, int line, uint64_t addr, enum tgdb_breakpoint_action b) { tgdb_request_ptr request_ptr; request_ptr = (tgdb_request_ptr)cgdb_malloc(sizeof (struct tgdb_request)); request_ptr->header = TGDB_REQUEST_MODIFY_BREAKPOINT; request_ptr->choice.modify_breakpoint.file = file ? cgdb_strdup(file) : NULL; request_ptr->choice.modify_breakpoint.line = line; request_ptr->choice.modify_breakpoint.addr = addr; request_ptr->choice.modify_breakpoint.b = b; tgdb_run_or_queue_request(tgdb, request_ptr, false); }
char *a2_client_modify_breakpoint(struct annotate_two *a2, const char *file, int line, enum tgdb_breakpoint_action b) { char *val = (char *) cgdb_malloc(sizeof (char) * (strlen(file) + 128)); if (b == TGDB_BREAKPOINT_ADD) { sprintf(val, "break \"%s\":%d", file, line); return val; } else if (b == TGDB_BREAKPOINT_DELETE) { sprintf(val, "clear \"%s\":%d", file, line); return val; } else if (b == TGDB_TBREAKPOINT_ADD) { sprintf(val, "tbreak \"%s\":%d", file, line); return val; } else return NULL; }
/** * Modify's a breakpoint. * * \param tgdb * An instance of the tgdb library to operate on. * * \param file * The file to set the breakpoint in. * * \param line * The line in FILE to set the breakpoint in. * * \param b * Determines what the user wants to do with the breakpoint. * * @return * Will return as a tgdb request command on success, otherwise NULL. */ tgdb_request_ptr Ctgdb::Request_modify_breakpoint(const char *file, int line, enum tgdb_breakpoint_action b) { tgdb_request_ptr request_ptr; request_ptr = (tgdb_request_ptr) cgdb_malloc (sizeof (struct tgdb_request)); if (!request_ptr) return NULL; request_ptr->header = TGDB_REQUEST_MODIFY_BREAKPOINT; request_ptr->choice.modify_breakpoint.file = (const char *) cgdb_strdup (file); request_ptr->choice.modify_breakpoint.line = line; request_ptr->choice.modify_breakpoint.b = b; return request_ptr; }
/** * This sends a console command to the debugger (GDB). * * \param tgdb * An instance of the tgdb library to operate on. * * \param command * The null terminated command to pass to GDB as a console command. * * \return * Will return as a tgdb request command on success, otherwise NULL. */ tgdb_request_ptr Ctgdb::Request_run_console_command(const char *command) { tgdb_request_ptr request_ptr; if (!command) return NULL; request_ptr = (tgdb_request_ptr) cgdb_malloc (sizeof (struct tgdb_request)); if (!request_ptr) return NULL; request_ptr->header = TGDB_REQUEST_CONSOLE_COMMAND; request_ptr->choice.console_command.command = (const char *) cgdb_strdup (command); return request_ptr; }
struct tgdb_command * tgdb_command_create (const char *tgdb_command_data, enum tgdb_command_choice command_choice, void *client_data) { struct tgdb_command *tc; tc = (struct tgdb_command *)cgdb_malloc ( sizeof ( struct tgdb_command ) ); if (tgdb_command_data) tc->tgdb_command_data = strdup (tgdb_command_data); else tc->tgdb_command_data = NULL; tc->command_choice = command_choice; tc->tgdb_client_private_data = client_data; return tc; }
/* initialize_annotate_two * * initializes an annotate_two subsystem and sets up all initial values. */ static struct annotate_two *initialize_annotate_two(void) { struct annotate_two *a2 = (struct annotate_two *) cgdb_malloc(sizeof (struct annotate_two)); a2->tgdb_initialized = 0; a2->debugger_stdin = -1; a2->debugger_out = -1; a2->pty_pair = NULL; /* null terminate */ a2->config_dir[0] = '\0'; a2->a2_gdb_init_file[0] = '\0'; a2->cur_response_list = NULL; return a2; }
int cgdbrc_attach(enum cgdbrc_option_kind option, cgdbrc_notify notify, int *handle) { struct cgdbrc_attach_item *item = (struct cgdbrc_attach_item *) cgdb_malloc(sizeof (struct cgdbrc_attach_item)); item->option = option; item->handle = cgdbrc_attach_handle++; item->notify_hook = notify; if (!cgdbrc_attach_list) cgdbrc_attach_list = std_list_create(destroy_notify); std_list_append(cgdbrc_attach_list, item); if (handle) *handle = item->handle; return 0; }
int rline_get_keyseq (struct rline *rline, const char *named_function, std_list keyseq_list) { rl_command_func_t *func; char **invoking_keyseqs = NULL; char **invoking_keyseqs_cur = NULL; char *new_keyseq = NULL; int len; if (!keyseq_list) return -1; func = rl_named_function (named_function); if (func == 0) return 0; invoking_keyseqs = rl_invoking_keyseqs (func); invoking_keyseqs_cur = invoking_keyseqs; while (invoking_keyseqs_cur && (*invoking_keyseqs_cur)) { new_keyseq = (char *)cgdb_malloc ((2 * strlen (*invoking_keyseqs_cur)) + 1); if (rl_translate_keyseq (*invoking_keyseqs_cur, new_keyseq, &len)) { free (new_keyseq); free (*invoking_keyseqs_cur); /* Can't do much about readline failing, just continue on. */ continue; } /* If the append function breaks, in serious trouble */ std_list_append (keyseq_list, new_keyseq); free (*invoking_keyseqs_cur); invoking_keyseqs_cur++; } free (invoking_keyseqs); return 0; }