reimplement run-to-line and run-to-address with temporary user breakpoints which die-on-stop, which provides the desired flow for e.g. run-to-line while nothing runs

This commit is contained in:
Ryan Fleury
2024-01-25 07:07:22 -08:00
parent ed7d31d7ea
commit 7cf0854178
7 changed files with 83 additions and 76 deletions
+8 -7
View File
@@ -2206,16 +2206,17 @@ ctrl_thread__launch_and_init(CTRL_Msg *msg)
{
CTRL_EventList evts = {0};
CTRL_Event *event = ctrl_event_list_push(scratch.arena, &evts);
event->kind = CTRL_EventKind_Stopped;
event->kind = CTRL_EventKind_Stopped;
event->msg_id = msg->msg_id;
if(stop_event != 0)
{
event->cause = ctrl_event_cause_from_demon_event_kind(stop_event->kind);
event->machine_id = CTRL_MachineID_Client;
event->entity = ctrl_handle_from_demon(stop_event->thread);
event->parent = ctrl_handle_from_demon(stop_event->process);
event->cause = ctrl_event_cause_from_demon_event_kind(stop_event->kind);
event->machine_id = CTRL_MachineID_Client;
event->entity = ctrl_handle_from_demon(stop_event->thread);
event->parent = ctrl_handle_from_demon(stop_event->process);
event->exception_code = stop_event->code;
event->vaddr_rng = r1u64(stop_event->address, stop_event->address);
event->rip_vaddr = stop_event->instruction_pointer;
event->vaddr_rng = r1u64(stop_event->address, stop_event->address);
event->rip_vaddr = stop_event->instruction_pointer;
}
ctrl_c2u_push_events(&evts);
}
+43 -8
View File
@@ -1621,7 +1621,7 @@ df_entity_notify_mutation(DF_Entity *entity)
DF_CmdParams p = {0};
df_push_cmd__root(&p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_WriteProfileData));
}
if(e == entity && flags & DF_EntityKindFlag_LeafMutationSoftHalt)
if(e == entity && flags & DF_EntityKindFlag_LeafMutationSoftHalt && df_ctrl_targets_running())
{
df_state->entities_mut_soft_halt = 1;
}
@@ -1629,7 +1629,7 @@ df_entity_notify_mutation(DF_Entity *entity)
{
df_state->entities_mut_dbg_info_map = 1;
}
if(flags & DF_EntityKindFlag_TreeMutationSoftHalt)
if(flags & DF_EntityKindFlag_TreeMutationSoftHalt && df_ctrl_targets_running())
{
df_state->entities_mut_soft_halt = 1;
}
@@ -6440,6 +6440,23 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt)
DF_CmdParams params = df_cmd_params_zero();
df_cmd_list_push(arena, cmds, &params, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_Error));
}
// rjf: kill all entities which are marked to die on stop
{
DF_Entity *request = df_entity_from_id(event->msg_id);
if(df_entity_is_nil(request))
{
for(DF_Entity *entity = df_entity_root();
!df_entity_is_nil(entity);
entity = df_entity_rec_df_pre(entity, df_entity_root()).next)
{
if(entity->flags & DF_EntityFlag_DiesOnRunStop)
{
df_entity_mark_for_deletion(entity);
}
}
}
}
}break;
//- rjf: entity creation/deletion
@@ -7036,7 +7053,6 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt)
case DF_CoreCmdKind_StepIntoLine:
case DF_CoreCmdKind_StepOverLine:
case DF_CoreCmdKind_StepOut:
case DF_CoreCmdKind_RunToAddress:
{
DF_Entity *thread = df_entity_from_handle(params.entity);
if(df_ctrl_targets_running())
@@ -7088,11 +7104,6 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt)
good = 0;
}
}break;
case DF_CoreCmdKind_RunToAddress:
{
CTRL_Trap trap = {CTRL_TrapFlag_EndStepping|CTRL_TrapFlag_IgnoreStackPointerCheck, params.vaddr};
ctrl_trap_list_push(scratch.arena, &traps, &trap);
}break;
}
if(good && traps.count != 0)
{
@@ -7127,6 +7138,30 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt)
}break;
//- rjf: high-level composite target control operations
case DF_CoreCmdKind_RunToLine:
{
DF_Entity *file = df_entity_from_handle(params.entity);
TxtPt point = params.text_point;
if(file->kind == DF_EntityKind_File)
{
DF_Entity *bp = df_entity_alloc(0, file, DF_EntityKind_Breakpoint);
bp->flags |= DF_EntityFlag_DiesOnRunStop;
df_entity_equip_b32(bp, 1);
df_entity_equip_txt_pt(bp, point);
df_entity_equip_cfg_src(bp, DF_CfgSrc_Transient);
DF_CmdParams p = df_cmd_params_zero();
df_cmd_list_push(arena, cmds, &p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_Run));
}
}break;
case DF_CoreCmdKind_RunToAddress:
{
DF_Entity *bp = df_entity_alloc(0, df_entity_root(), DF_EntityKind_Breakpoint);
bp->flags |= DF_EntityFlag_DiesOnRunStop;
df_entity_equip_vaddr(bp, params.vaddr);
df_entity_equip_cfg_src(bp, DF_CfgSrc_Transient);
DF_CmdParams p = df_cmd_params_zero();
df_cmd_list_push(arena, cmds, &p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_Run));
}break;
case DF_CoreCmdKind_Run:
{
DF_CmdParams params = df_cmd_params_zero();
+12 -11
View File
@@ -463,21 +463,22 @@ enum
DF_EntityFlag_HasRng1U64 = (1<<5),
DF_EntityFlag_HasColor = (1<<6),
DF_EntityFlag_DiesWithTime = (1<<7),
DF_EntityFlag_DiesOnRunStop = (1<<8),
//- rjf: ctrl entity equipment
DF_EntityFlag_HasCtrlMachineID = (1<<8),
DF_EntityFlag_HasCtrlHandle = (1<<9),
DF_EntityFlag_HasArch = (1<<10),
DF_EntityFlag_HasCtrlID = (1<<11),
DF_EntityFlag_HasStackBase = (1<<12),
DF_EntityFlag_HasTLSRoot = (1<<13),
DF_EntityFlag_HasVAddrRng = (1<<14),
DF_EntityFlag_HasVAddr = (1<<15),
DF_EntityFlag_HasCtrlMachineID = (1<<9),
DF_EntityFlag_HasCtrlHandle = (1<<10),
DF_EntityFlag_HasArch = (1<<11),
DF_EntityFlag_HasCtrlID = (1<<12),
DF_EntityFlag_HasStackBase = (1<<13),
DF_EntityFlag_HasTLSRoot = (1<<14),
DF_EntityFlag_HasVAddrRng = (1<<15),
DF_EntityFlag_HasVAddr = (1<<16),
//- rjf: file properties
DF_EntityFlag_IsFolder = (1<<16),
DF_EntityFlag_IsMissing = (1<<17),
DF_EntityFlag_Output = (1<<18), // NOTE(rjf): might be missing, but written by us
DF_EntityFlag_IsFolder = (1<<17),
DF_EntityFlag_IsMissing = (1<<18),
DF_EntityFlag_Output = (1<<19), // NOTE(rjf): might be missing, but written by us
//- rjf: deletion
DF_EntityFlag_MarkedForDeletion = (1<<31),
+3 -1
View File
@@ -10,6 +10,7 @@ DF_CfgSrcTable:
{"user" User LoadUser WriteUserData ApplyUserData }
{"profile" Profile LoadProfile WriteProfileData ApplyProfileData }
{"command_line" CommandLine Null Null Null }
{"transient" Transient Null Null Null }
}
////////////////////////////////
@@ -128,12 +129,13 @@ DF_CoreCmdTable:// | | |
{StepIntoLine 0 Null Nil 0 0 0 0 0 0 StepInto "step_into_line" "Step Into (Line)" "Performs a step that goes into calls, at the source code line level." "step,thread" }
{StepOverLine 0 Null Nil 0 0 0 0 0 0 StepOver "step_over_line" "Step Over (Line)" "Performs a step that skips calls, at the source code line level." "step,thread" }
{StepOut 0 Null Nil 0 0 0 0 0 0 StepOut "step_out" "Step Out" "Runs to the end of the current function and exits it." "" }
{RunToAddress 0 VirtualAddr Nil 0 0 0 0 1 1 PlayStepForward "run_to_address" "Run To Address" "Runs the selected thread to the specified address." "" }
{Halt 0 Null Nil 0 0 0 0 0 0 Pause "halt" "Halt" "Halts all running processes." "pause" }
{SoftHaltRefresh 0 Null Nil 0 0 0 0 0 0 Refresh "soft_halt_refresh" "Soft Halt Refresh" "Interrupts all running processes to collect data, and then resumes them." "" }
{SetThreadIP 1 VirtualAddr Nil 0 0 0 0 1 1 Null "set_thread_ip" "Set Thread IP" "Sets the passed thread's instruction pointer at the passed address." "" }
//- rjf: high-level composite target control operations
{RunToLine 1 Null Nil 0 0 0 0 0 0 Play "run_to_line" "Run To Line" "Runs until a particular source line is hit." "" }
{RunToAddress 0 VirtualAddr Nil 0 0 0 0 1 1 PlayStepForward "run_to_address" "Run To Address" "Runs until a particular address is hit." "" }
{Run 0 Null Nil 0 0 0 0 0 0 Play "run" "Run" "Runs all targets after starting them if they have not been started yet." "play" }
{Restart 0 Null Nil 0 0 0 0 0 0 Redo "restart" "Restart" "Kills all running processes, then restarts the targets which were used to launch all current processes (if any)." "restart,retry" }
{StepInto 0 Null Nil 0 0 0 0 0 0 StepInto "step_into" "Step Into" "Steps once, possibly into function calls, for either line or instructions." "" }
+2 -1
View File
@@ -20,10 +20,11 @@ DF_CmdSpecInfo df_g_core_cmd_kind_spec_info_table[] =
{ str8_lit_comp("step_into_line"), str8_lit_comp("Performs a step that goes into calls, at the source code line level."), str8_lit_comp("step,thread"), str8_lit_comp("Step Into (Line)"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_StepInto},
{ str8_lit_comp("step_over_line"), str8_lit_comp("Performs a step that skips calls, at the source code line level."), str8_lit_comp("step,thread"), str8_lit_comp("Step Over (Line)"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_StepOver},
{ str8_lit_comp("step_out"), str8_lit_comp("Runs to the end of the current function and exits it."), str8_lit_comp(""), str8_lit_comp("Step Out"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_StepOut},
{ str8_lit_comp("run_to_address"), str8_lit_comp("Runs the selected thread to the specified address."), str8_lit_comp(""), str8_lit_comp("Run To Address"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_VirtualAddr, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*1)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_PlayStepForward},
{ str8_lit_comp("halt"), str8_lit_comp("Halts all running processes."), str8_lit_comp("pause"), str8_lit_comp("Halt"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Pause},
{ str8_lit_comp("soft_halt_refresh"), str8_lit_comp("Interrupts all running processes to collect data, and then resumes them."), str8_lit_comp(""), str8_lit_comp("Soft Halt Refresh"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Refresh},
{ str8_lit_comp("set_thread_ip"), str8_lit_comp("Sets the passed thread's instruction pointer at the passed address."), str8_lit_comp(""), str8_lit_comp("Set Thread IP"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_VirtualAddr, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*1)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_Null},
{ str8_lit_comp("run_to_line"), str8_lit_comp("Runs until a particular source line is hit."), str8_lit_comp(""), str8_lit_comp("Run To Line"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Play},
{ str8_lit_comp("run_to_address"), str8_lit_comp("Runs until a particular address is hit."), str8_lit_comp(""), str8_lit_comp("Run To Address"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_VirtualAddr, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*1)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_PlayStepForward},
{ str8_lit_comp("run"), str8_lit_comp("Runs all targets after starting them if they have not been started yet."), str8_lit_comp("play"), str8_lit_comp("Run"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Play},
{ str8_lit_comp("restart"), str8_lit_comp("Kills all running processes, then restarts the targets which were used to launch all current processes (if any)."), str8_lit_comp("restart,retry"), str8_lit_comp("Restart"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Redo},
{ str8_lit_comp("step_into"), str8_lit_comp("Steps once, possibly into function calls, for either line or instructions."), str8_lit_comp(""), str8_lit_comp("Step Into"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_StepInto},
+7 -1
View File
@@ -11,6 +11,7 @@ typedef enum DF_CfgSrc
DF_CfgSrc_User,
DF_CfgSrc_Profile,
DF_CfgSrc_CommandLine,
DF_CfgSrc_Transient,
DF_CfgSrc_COUNT
} DF_CfgSrc;
@@ -70,10 +71,11 @@ DF_CoreCmdKind_StepOverInst,
DF_CoreCmdKind_StepIntoLine,
DF_CoreCmdKind_StepOverLine,
DF_CoreCmdKind_StepOut,
DF_CoreCmdKind_RunToAddress,
DF_CoreCmdKind_Halt,
DF_CoreCmdKind_SoftHaltRefresh,
DF_CoreCmdKind_SetThreadIP,
DF_CoreCmdKind_RunToLine,
DF_CoreCmdKind_RunToAddress,
DF_CoreCmdKind_Run,
DF_CoreCmdKind_Restart,
DF_CoreCmdKind_StepInto,
@@ -1680,6 +1682,7 @@ String8 df_g_cfg_src_string_table[] =
str8_lit_comp("user"),
str8_lit_comp("profile"),
str8_lit_comp("command_line"),
str8_lit_comp("transient"),
};
DF_CoreCmdKind df_g_cfg_src_load_cmd_kind_table[] =
@@ -1687,6 +1690,7 @@ DF_CoreCmdKind df_g_cfg_src_load_cmd_kind_table[] =
DF_CoreCmdKind_LoadUser,
DF_CoreCmdKind_LoadProfile,
DF_CoreCmdKind_Null,
DF_CoreCmdKind_Null,
};
DF_CoreCmdKind df_g_cfg_src_write_cmd_kind_table[] =
@@ -1694,6 +1698,7 @@ DF_CoreCmdKind df_g_cfg_src_write_cmd_kind_table[] =
DF_CoreCmdKind_WriteUserData,
DF_CoreCmdKind_WriteProfileData,
DF_CoreCmdKind_Null,
DF_CoreCmdKind_Null,
};
DF_CoreCmdKind df_g_cfg_src_apply_cmd_kind_table[] =
@@ -1701,6 +1706,7 @@ DF_CoreCmdKind df_g_cfg_src_apply_cmd_kind_table[] =
DF_CoreCmdKind_ApplyUserData,
DF_CoreCmdKind_ApplyProfileData,
DF_CoreCmdKind_Null,
DF_CoreCmdKind_Null,
};
String8 df_g_icon_kind_text_table[] =
+8 -47
View File
@@ -4621,30 +4621,10 @@ DF_VIEW_CMD_FUNCTION_DEF(Code)
}break;
case DF_CoreCmdKind_RunToCursor:
{
Temp scratch = scratch_begin(0, 0);
DF_Entity *thread = df_entity_from_handle(cmd->params.entity);
S64 line_num = tv->cursor.line;
DF_TextLineSrc2DasmInfoListArray src2dasm = df_text_line_src2dasm_info_list_array_from_src_line_range(scratch.arena, entity, r1s64(line_num, line_num));
if(!df_entity_is_nil(thread) && src2dasm.count != 0)
{
DF_TextLineSrc2DasmInfoList *src2dasm_list = &src2dasm.v[0];
if(src2dasm_list->first != 0)
{
Rng1U64 voff_rng = src2dasm_list->first->v.voff_range;
DF_Entity *binary = src2dasm_list->first->v.binary;
DF_EntityList possible_modules = df_modules_from_binary_file(scratch.arena, binary);
DF_Entity *thread_dst_module = df_module_from_thread_candidates(thread, &possible_modules);
U64 thread_dst_voff = voff_rng.min;
if(!df_entity_is_nil(thread_dst_module) && thread_dst_voff != 0)
{
DF_CmdParams params = df_cmd_params_from_window(ws);
params.vaddr = df_vaddr_from_voff(thread_dst_module, thread_dst_voff);
df_cmd_params_mark_slot(&params, DF_CmdParamSlot_VirtualAddr);
df_push_cmd__root(&params, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_RunToAddress));
}
}
}
scratch_end(scratch);
DF_CmdParams params = df_cmd_params_from_view(ws, panel, view);
params.entity = view->entity;
params.text_point = tv->cursor;
df_push_cmd__root(&params, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_RunToLine));
}break;
case DF_CoreCmdKind_SetNextStatement:
{
@@ -5310,29 +5290,10 @@ DF_VIEW_UI_FUNCTION_DEF(Code)
//- rjf: run-to-line
if(sig.run_to_line_num != 0 && contains_1s64(visible_line_num_range, sig.run_to_line_num))
{
U64 line_idx = (sig.run_to_line_num-visible_line_num_range.min);
DF_TextLineSrc2DasmInfoList *src2dasm_list = &code_slice_params.line_src2dasm[line_idx];
if(src2dasm_list->first != 0)
{
Rng1U64 voff_rng = src2dasm_list->first->v.voff_range;
DF_Entity *binary = src2dasm_list->first->v.binary;
DF_EntityList possible_modules = df_modules_from_binary_file(scratch.arena, binary);
DF_Entity *thread = df_entity_from_handle(ctrl_ctx.thread);
DF_Entity *thread_dst_module = df_module_from_thread_candidates(thread, &possible_modules);
DF_Entity *module = thread_dst_module;
if(df_entity_is_nil(module))
{
module = df_first_entity_from_list(&possible_modules);
}
U64 voff = voff_rng.min;
if(!df_entity_is_nil(module) && voff != 0)
{
DF_CmdParams params = df_cmd_params_from_window(ws);
params.vaddr = df_vaddr_from_voff(module, voff);
df_cmd_params_mark_slot(&params, DF_CmdParamSlot_VirtualAddr);
df_push_cmd__root(&params, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_RunToAddress));
}
}
DF_CmdParams params = df_cmd_params_from_view(ws, panel, view);
params.entity = df_handle_from_entity(entity);
params.text_point = txt_pt(sig.run_to_line_num, 1);
df_push_cmd__root(&params, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_RunToLine));
}
//- rjf: go to disasm