/*********************************************************************** * break_check_delayed_bp * * Check is a registered delayed BP is now available. */ void break_check_delayed_bp(void) { struct dbg_lvalue lvalue; int i; struct dbg_delayed_bp* dbp = dbg_curr_process->delayed_bp; char hexbuf[MAX_OFFSET_TO_STR_LEN]; for (i = 0; i < dbg_curr_process->num_delayed_bp; i++) { if (dbp[i].is_symbol) { if (symbol_get_lvalue(dbp[i].u.symbol.name, dbp[i].u.symbol.lineno, &lvalue, TRUE) != sglv_found) continue; if (lvalue.cookie != DLV_TARGET) continue; } else lvalue.addr = dbp[i].u.addr; WINE_TRACE("trying to add delayed %s-bp\n", dbp[i].is_symbol ? "S" : "A"); if (!dbp[i].is_symbol) WINE_TRACE("\t%04x:%s\n", dbp[i].u.addr.Segment, memory_offset_to_string(hexbuf, dbp[i].u.addr.Offset, 0)); else WINE_TRACE("\t'%s' @ %d\n", dbp[i].u.symbol.name, dbp[i].u.symbol.lineno); if (break_add_break(&lvalue.addr, FALSE, dbp[i].software_bp)) memmove(&dbp[i], &dbp[i+1], (--dbg_curr_process->num_delayed_bp - i) * sizeof(*dbp)); } }
/*********************************************************************** * break_add_break_from_id * * Add a breakpoint from a function name (and eventually a line #) */ void break_add_break_from_id(const char *name, int lineno, BOOL swbp) { struct dbg_lvalue lvalue; int i; switch (symbol_get_lvalue(name, lineno, &lvalue, TRUE)) { case sglv_found: break_add_break(&lvalue.addr, TRUE, swbp); return; case sglv_unknown: break; case sglv_aborted: /* user aborted symbol lookup */ return; } dbg_printf("Unable to add breakpoint, will check again when a new DLL is loaded\n"); for (i = 0; i < dbg_curr_process->num_delayed_bp; i++) { if (dbg_curr_process->delayed_bp[i].is_symbol && !strcmp(name, dbg_curr_process->delayed_bp[i].u.symbol.name) && lineno == dbg_curr_process->delayed_bp[i].u.symbol.lineno) return; } dbg_curr_process->delayed_bp = dbg_heap_realloc(dbg_curr_process->delayed_bp, sizeof(struct dbg_delayed_bp) * ++dbg_curr_process->num_delayed_bp); dbg_curr_process->delayed_bp[dbg_curr_process->num_delayed_bp - 1].is_symbol = TRUE; dbg_curr_process->delayed_bp[dbg_curr_process->num_delayed_bp - 1].software_bp = swbp; dbg_curr_process->delayed_bp[dbg_curr_process->num_delayed_bp - 1].u.symbol.name = strcpy(HeapAlloc(GetProcessHeap(), 0, strlen(name) + 1), name); dbg_curr_process->delayed_bp[dbg_curr_process->num_delayed_bp - 1].u.symbol.lineno = lineno; }
/*********************************************************************** * break_add_break_from_lvalue * * Add a breakpoint. */ BOOL break_add_break_from_lvalue(const struct dbg_lvalue* lvalue, BOOL swbp) { ADDRESS64 addr; types_extract_as_address(lvalue, &addr); if (!break_add_break(&addr, TRUE, swbp)) { if (!DBG_IVAR(CanDeferOnBPByAddr)) { dbg_printf("Invalid address, can't set breakpoint\n" "You can turn on deferring bp by address by setting $CanDeferOnBPByAddr to 1\n"); return FALSE; } dbg_printf("Unable to add breakpoint, will check again any time a new DLL is loaded\n"); dbg_curr_process->delayed_bp = dbg_heap_realloc(dbg_curr_process->delayed_bp, sizeof(struct dbg_delayed_bp) * ++dbg_curr_process->num_delayed_bp); dbg_curr_process->delayed_bp[dbg_curr_process->num_delayed_bp - 1].is_symbol = FALSE; dbg_curr_process->delayed_bp[dbg_curr_process->num_delayed_bp - 1].software_bp = swbp; dbg_curr_process->delayed_bp[dbg_curr_process->num_delayed_bp - 1].u.addr = addr; return TRUE; } return FALSE; }
static void dbg_init_current_thread(void* start) { if (start) { if (dbg_curr_process->threads && !dbg_curr_process->threads->next && /* first thread ? */ DBG_IVAR(BreakAllThreadsStartup)) { ADDRESS64 addr; break_set_xpoints(FALSE); addr.Mode = AddrModeFlat; addr.Offset = (DWORD_PTR)start; break_add_break(&addr, TRUE, TRUE); break_set_xpoints(TRUE); } } }
/*********************************************************************** * break_add_break_from_lineno * * Add a breakpoint from a line number in current file */ void break_add_break_from_lineno(const char *filename, int lineno, BOOL swbp) { struct cb_break_lineno bkln; bkln.addr.Offset = 0; bkln.lineno = lineno; if (!filename) { DWORD disp; ADDRESS64 curr; IMAGEHLP_LINE64 il; DWORD_PTR linear; memory_get_current_pc(&curr); linear = (DWORD_PTR)memory_to_linear_addr(&curr); il.SizeOfStruct = sizeof(il); if (!SymGetLineFromAddr64(dbg_curr_process->handle, linear, &disp, &il)) { dbg_printf("Unable to add breakpoint (unknown address %lx)\n", linear); return; } filename = il.FileName; SymEnumLines(dbg_curr_process->handle, linear, NULL, filename, line_cb, &bkln); } else { /* we have to enumerate across modules */ bkln.filename = filename; SymEnumerateModulesW64(dbg_curr_process->handle, mcb, &bkln); } if (bkln.addr.Offset) break_add_break(&bkln.addr, TRUE, swbp); else dbg_printf("Unknown line number\n" "(either out of file, or no code at given line number)\n"); }