/* Called by Geany before unloading the plugin. * Here any UI changes should be removed, memory freed and any other finalization done. * Be sure to leave Geany as it was before plugin_init(). */ void plugin_cleanup(void) { /* stop debugger if running */ if (DBS_IDLE != debug_get_state()) { debug_stop(); while (DBS_IDLE != debug_get_state()) g_main_context_iteration(NULL,FALSE); } config_destroy(); pixbufs_destroy(); debug_destroy(); breaks_destroy(); dpaned_destroy(); envtree_destroy(); /* release other allocated strings and objects */ gtk_widget_destroy(hbox); }
/* * oneshot_attach() * Attach a timer to the list. */ void oneshot_attach(struct oneshot *timer) { spinlock_lock(&oneshot_lock); if (DEBUG) { if (timer->os_next) { debug_stop(); while (1) { debug_print_pstr("\fAttach timer: "); debug_print16((addr_t)timer); debug_print_pstr(" - is already"); debug_wait_button(); debug_stack_trace(); } } } timer->os_next = oneshot_list; oneshot_list = timer; oneshot_ref(timer); spinlock_unlock(&oneshot_lock); }
/* * Occures when key is pressed. * Handles debug Run/Stop/... and add/remove breakpoint activities */ gboolean keys_callback(guint key_id) { switch (key_id) { case KEY_RUN: debug_run(); break; case KEY_STOP: debug_stop(); break; case KEY_RESTART: debug_restart(); break; case KEY_STEP_OVER: debug_step_over(); break; case KEY_STEP_INTO: debug_step_into(); break; case KEY_STEP_OUT: debug_step_out(); break; case KEY_EXECUTE_UNTIL: { GeanyDocument *doc = document_get_current(); if (doc) { int line = sci_get_current_line(doc->editor->sci) + 1; debug_execute_until(DOC_FILENAME(doc), line); } break; } case KEY_BREAKPOINT: { GeanyDocument *doc = document_get_current(); if (doc) { int line = sci_get_current_line(doc->editor->sci) + 1; break_state bs = breaks_get_state(DOC_FILENAME(doc), line); if (BS_NOT_SET == bs) breaks_add(DOC_FILENAME(doc), line, NULL, TRUE, 0); else if (BS_ENABLED == bs) breaks_remove(DOC_FILENAME(doc), line); else if (BS_DISABLED == bs) breaks_switch(DOC_FILENAME(doc), line); scintilla_send_message(doc->editor->sci, SCI_SETFOCUS, TRUE, 0); } break; } case KEY_CURRENT_INSTRUCTION: { if (DBS_STOPPED == debug_get_state() && debug_current_instruction_have_sources()) { debug_jump_to_current_instruction(); gtk_widget_set_sensitive(tab_call_stack, FALSE); stree_select_first_frame(FALSE); gtk_widget_set_sensitive(tab_call_stack, TRUE); } } } return TRUE; }
static void kerext_debug_process(void *args) { PROCESS *prp; THREAD *thp, *act = actives[KERNCPU]; DEBUG *dep; struct kerargs_debug_process *kap = args; int status; int stopped; int tid; if(!(prp = lookup_pid(kap->pid))) { kererr(act, ESRCH); return; } dep = prp->debugger; if(kap->request == NTO_DEBUG_PROCESS_INFO || (prp->flags & _NTO_PF_TERMING)) { tid = 0; } else if(dep && kap->tid == 0) { tid = dep->tid + 1; } else { tid = kap->tid; } thp = 0; if(tid > 0 && !(thp = vector_search(&prp->threads, tid - 1, (kap->request == NTO_DEBUG_THREAD_INFO || kap->request == NTO_DEBUG_STOP) ? (unsigned *)&tid : 0))) { kererr(act, ESRCH); return; } stopped = 0; if(thp && ((thp->flags & _NTO_TF_TO_BE_STOPPED) || (thp->state != STATE_RUNNING && thp->state != STATE_READY))) { stopped = 1; } status = EINVAL; switch(kap->request) { case NTO_DEBUG_PROCESS_INFO: // pid:na:debug_process_t status = debug_process(prp, &kap->data->process); break; case NTO_DEBUG_THREAD_INFO: // pid:tid:debug_thread_t status = debug_thread(prp, thp, &kap->data->thread); break; case NTO_DEBUG_GET_GREG: // pid:tid:debug_greg_t if(thp) { memcpy(&kap->data->greg, &thp->reg, sizeof thp->reg); status = EOK; } break; case NTO_DEBUG_SET_GREG: // pid:tid:debug_greg_t if(stopped) { lock_kernel(); cpu_greg_load(thp, (CPU_REGISTERS *)&kap->data->greg); status = EOK; } break; case NTO_DEBUG_GET_FPREG: // pid:tid:debug_fpreg_t if(thp) { FPU_REGISTERS *fpudata = FPUDATA_PTR(thp->fpudata); int cpu = FPUDATA_CPU(thp->fpudata); status = ENXIO; if(fpudata) { if(FPUDATA_INUSE(thp->fpudata) && cpu != KERNCPU) { // In use on another CPU; send ipi, restart kernel call SENDIPI(cpu, IPI_CONTEXT_SAVE); KERCALL_RESTART(act); return; } if(actives_fpu[thp->runcpu] == thp) { if(KERNCPU == thp->runcpu) { cpu_force_fpu_save(thp); actives_fpu[KERNCPU] = NULL; } else { // We should not get here crash(); } } memcpy(&kap->data->fpreg, fpudata, sizeof *fpudata); status = EOK; } else if(thp->un.lcl.tls && thp->un.lcl.tls->__fpuemu_data) { // @@@ NEED TO FIND PROPER SIZE OF EMULATOR DATA memcpy(&kap->data->fpreg, thp->un.lcl.tls->__fpuemu_data, sizeof(*fpudata) + 256); status = EOK; } } break; case NTO_DEBUG_SET_FPREG: // pid:tid:debug_fpreg_t if(thp && stopped) { FPU_REGISTERS *fpudata = FPUDATA_PTR(thp->fpudata); int cpu = FPUDATA_CPU(thp->fpudata); status = ENXIO; if(thp->fpudata) { if(FPUDATA_INUSE(thp->fpudata) && cpu != KERNCPU) { // In use on another CPU; send ipi, restart kernel call SENDIPI(cpu, IPI_CONTEXT_SAVE); KERCALL_RESTART(act); return; } if(actives_fpu[thp->runcpu] == thp) { if(KERNCPU == thp->runcpu) { cpu_force_fpu_save(thp); actives_fpu[KERNCPU] = NULL; } else { // We should not get here crash(); } } memcpy(fpudata, &kap->data->fpreg, sizeof *fpudata); status = EOK; } else if(thp->un.lcl.tls && thp->un.lcl.tls->__fpuemu_data) { // @@@ NEED TO FIND PROPER SIZE OF EMULATOR DATA memcpy(thp->un.lcl.tls->__fpuemu_data, &kap->data->fpreg, sizeof(*fpudata) + 256); status = EOK; } } break; case NTO_DEBUG_STOP: // pid:na:na if(dep) { status = debug_stop(prp); } break; case NTO_DEBUG_RUN: // pid:tid:debug_run_t if(dep && stopped) { status = debug_run(prp, &kap->data->run); } break; case NTO_DEBUG_CURTHREAD: // pid:tid:NULL if(dep) { lock_kernel(); SETKSTATUS(act, dep->tid + 1); if(thp) { dep->tid = thp->tid; } return; } break; case NTO_DEBUG_FREEZE: // pid:tid:NULL if(thp == NULL){ status = EINVAL; break; } if(stopped) { lock_kernel(); thp->flags |= _NTO_TF_FROZEN; } break; case NTO_DEBUG_THAW: // pid:tid:NULL if(thp == NULL){ status = EINVAL; break; } if(stopped) { lock_kernel(); thp->flags &= ~_NTO_TF_FROZEN; } break; case NTO_DEBUG_BREAK: // pid:na:debug_break_t if(dep && stopped) { status = debug_break(prp, &kap->data->brk); } break; case NTO_DEBUG_GET_BREAKLIST: // pid:na:debug_breaklist_t status = debug_break_list(prp, &kap->data->brklist); break; case NTO_DEBUG_SET_FLAG: // pid:na:uint32_t if(dep && !(kap->data->flags & ~_DEBUG_FLAG_MASK)) { lock_kernel(); dep->flags |= kap->data->flags; } break; case NTO_DEBUG_CLEAR_FLAG: // pid:na:uint32_t if(dep && !(kap->data->flags & ~_DEBUG_FLAG_MASK)) { lock_kernel(); dep->flags &= ~kap->data->flags; } break; case NTO_DEBUG_GET_ALTREG: // pid:tid:debug_altreg_t if(thp) { status = cpu_debug_get_altregs(thp, &kap->data->altreg); } break; case NTO_DEBUG_SET_ALTREG: // pid:tid:debug_altreg_t if(thp) { status = cpu_debug_set_altregs(thp, &kap->data->altreg); } break; case NTO_DEBUG_GET_PERFREG: if ( thp ) { status = cpu_debug_get_perfregs(thp, &kap->data->perfreg); } break; case NTO_DEBUG_SET_PERFREG: if ( thp && !stopped ) status = EINVAL; else { if ( (kap->data->flags & ~PERFREGS_ENABLED_FLAG) == cpu_perfreg_id() ) { status = cpu_debug_set_perfregs(thp, &kap->data->perfreg); } else status = ENODEV; } break; } if(status != EOK) { kererr(act, status); } else { lock_kernel(); SETKSTATUS(act, 0); } }
/*! main */ int main(void) { struct debug_t *debug; struct programs_t *progs; struct cmdli_t *cmdli; /* convenient pre-allocated structure */ struct tm *tm_clock; char c; /* anti warning for non initialized variables */ debug = NULL; progs = NULL; cmdli = NULL; tm_clock = NULL; /* Init sequence, turn on both led */ led_init(); led_set(BOTH, ON); io_init(); usb_init(); debug = debug_init(debug); progs = prog_init(progs); cmdli = cmdli_init(cmdli); tm_clock = date_init(tm_clock, debug); set_sleep_mode(SLEEP_MODE_PWR_SAVE); sei(); date_hwclock_start(); led_set(BOTH, OFF); while (1) { /* PC is connected but debug is off. */ if (usb_connected && (!debug->active)) debug_start(debug); if (debug->active && (!usb_connected)) debug_stop(debug); /* If PC is connected * then check for a command sent from the user * and execute it. * Anyway do NOT go to sleep. */ if (debug->active) { c = uart_getchar(0, 0); if (c) { /* echo */ uart_putchar(0, c); cmdli_exec(c, cmdli, progs, debug); } } else { go_to_sleep(progs->valve, debug); if (prog_alarm(progs) && flag_get(progs, FL_LED)) led_set(RED, BLINK); } /* if there is a job to do (open, close valves). */ if (date_timetorun(tm_clock, debug)) job_on_the_field(progs, debug, tm_clock); } /* This part should never be reached */ date_hwclock_stop(); cli(); date_free(tm_clock); cmdli_free(cmdli); prog_free(progs); debug_free(debug); return(0); }