XSLT存档  

不及格的程序员-八神

 查看分类:  ASP.NET XML/XSLT JavaScripT   我的MSN空间Blog

前文提要:

在VC6.0之后出现的VS系列开发工具都具有的调试功能:移动指针更改执行流,VC6不支持这个UI操作。

调试程序暂停时,源代码或“反汇编”窗口边距处的黄色箭头标记要运行的下一条语句的位置。 你可以通过移动此箭头来更改要运行的下一条语句。 你可以跳过代码,或者返回上一行。 在某些情况下移动指针很有用,例如,跳过包含已知 bug 的代码。

突发在奇想之后,想到了改变寄存器EIP的值来实现,下面这段英文介绍了什么是改变执行流,文尾给出VC6环境下如何实现。


Move the pointer to change the execution flow

When the debugger is paused, a yellow arrow in the margin of the source code or Disassembly window marks the location of the statement that will run next. You can change the next statement that will run by moving this arrow. You can skip over code or return to a previous line. Moving the pointer is useful for situations like skipping code that contains a known bug.

Animation that shows how to move the pointer.

If you want to change the next statement that will run, the debugger must be in break mode. In the source code or Disassembly window, drag the yellow arrow to a different line, or right-click the line you want to run next and select Set Next Statement.

The program counter jumps directly to the new location. Instructions between the old and new execution points aren't run. But if you move the execution point backwards, the intervening instructions aren't undone.

 Caution

  • Moving the next statement to another function or scope usually causes call-stack corruption, which causes a runtime error or exception. If you try to move the next statement to another scope, the debugger gives you a warning and a chance to cancel the operation.
  • In Visual Basic, you can't move the next statement to another scope or function.
  • In native C++, if you have runtime checks enabled, setting the next statement can cause an exception when execution reaches the end of the method.
  • When Edit and Continue is enabled, Set Next Statement fails if you've made edits that Edit and Continue can't remap immediately. This situation can occur, for example, if you've edited code in a catch block. When this happens, an error message tells you that the operation isn't supported.
  • In managed code, you can't move the next statement if:
    • The next statement is in a different method than the current statement.
    • Debugging was started by Just-In-Time debugging.
    • A call stack unwind is in progress.
    • A System.StackOverflowException or System.Threading.ThreadAbortException exception has been thrown.

在“寄存器”窗口中,使用 TAB 键或鼠标将插入点移动到要更改的值。开始键入时,光标必须位于要覆盖的值的前面,键入新值。

  更改寄存器值(尤其是在 EIP 和 EBP 寄存器中)会影响程序执行。

  由于浮点数的十进制到二进制转换精度原因,编辑浮点值可能会导致轻微的不准确,即使看似无害的编辑也可能导致浮点寄存器中某些最低有效位发生变化。


熟悉Visual Studio开发工具的朋友们都已经习惯在调试代码时,通过拖动指令光标位置实现代码指令跳转(跳过某些不想要的条件判断),此功能比单步执行要灵活许多。

碰到手里还有VC6的老C++项目时,突然没有这个功能,非常不适应,在Google还未退出中国时就想过这个问题,水平有限也没有搜到解决办法。

就在昨天,想到了一招直接手动修改EIP指令来实现,简单介绍一下 VC6环境修改CPU寄存器的两种方法,也许对一部分朋友还是有些帮助的。

下面是VC6的环境示意图:版权:不及格的程序员-八神

图中分别列出了源代码与反汇编代码窗体,同时也列出了寄存器窗口与右下角的变量观察辅助对话框

我们可以直接点击寄存器窗体中的 EIP 寄存器变量值的位置(不要双击,在要修改的位置前面单击即可)或是在变量观察对话框中双击value部分

需要注意:变量观察名子输入的是 EIP ,实际情况是需要输入@EIP的,这样不会与本地同名变量起冲突的

我们看到源码中当前指令执行到0X00A70B5E,同时EIP的值也是这个,我可改变它为:00A70B77,这样代码再次运行时,将直接实现跳转,略过前面的IF判断指令。

曲线实现了【移动指针更改执行流】,前面有英文注解, 需要注意的条件 :)

版权:不及格的程序员-八神


 2023-03-12更新:VC6 可以在源代码(反汇编窗口也可以)中通过右键菜单中的 set next statement项操作,功能同我上面描述。

Set next statement

I haven’t had a chance to post much recently, but I ran into a nice mail on an internal alias that listed the restrictions of set next statement. Set next statement is a very powerful feature of the debugger that allows the IP (instruction pointer) to be moved. It’s particularly useful when combined with Edit and Continue. This feature can be accessed from the context menu of the editor when the debugger is active. It may also be accessed by simply dragging the yellow arrow that appears on the left hand side of the screen while debugging. There are a number of restrictions associated with changing the IP including:

  • It can only be set within the same function/method
  • There are restrictions around setting it into or out of a catch block (exception handler)
  • It must usually be moved to source lines
  • The IP cannot be set when the debugger is stopped at a first chance exception
  • The IP can only be set in the active frame (the frame that is actually executing). That is, you cannot go 6 frames up the call stack and try to change the return address.

The most important thing to understand about this feature is that there is no real magic going on. It does a very minimal amount of work to move the IP; it does not try to change values back to their previous state if the IP is moved higher up in a method. If you’re tracking down a bug in your application, it’s often useful to step over most methods until something unexpected happens (e.g. a return value isn’t what you expect). You can then use set next statement to re-run the method but this time step into it and examine what went wrong. This can help track down bugs much faster, and of course, with Edit and Continue you can often fix the problem and then re-run the offending block of code to see if the change worked.

Imagine that you have this simple, somewhat useless bit of code:

using System;

class Example

{

static void Main(string[] args)

{

int initialValue = 20;

initialValue++;

Console.WriteLine(initialValue);

}

}

Let’s suppose that you’re debugging this and your IP is located on Console.WriteLine:

IP

Now you right-click on the source line containing initialValue++ and select “Set Next Statement”:

IPSet

Finally you hit F5 to finish running the application. The value written to the console is 22, not 21. Again, this is because Set Next Statement doesn’t perform any kind of state analysis, it simply moves the IP to the location indicated. In this case, it’s possible to get the original behavior by simply moving the IP up to the source line that sets the value of initialValue. That’s trivial in this case since the initial assignment is immediately above the modification. If there is a significant amount of code that you don’t want to re-run, then you can also modify the value in the locals/watch/etc. windows instead.


 

Java方面

This is possible...

http://help.eclipse.org/galileo/index.jsp?topic=/org.eclipse.jdt.doc.user/tips/jdt_tips.html

Drop to frame - When stepping through your code, you might occasionally step too far, or step over a line you meant to step into. Rather than restarting your debug session, you can use the Drop to Frame action to quickly go back to the beginning of a method. Select the stack frame corresponding to the Java method you wish to restart, and select Drop to Frame from Debug view toolbar or the stack frame's context menu. The current instruction pointer will be reset to the first executable statement in the method. This works for non-top stack frames as well.

Note that Drop to frame is only available when debugging with a 1.4 or higher VM, or the J9 VM. There are some situations where a JVM may be unable to pop the desired frames from the stack. For example, it is generally impossible to drop to the bottom frame of the stack or to any frame below a native method.

posted on 2023-02-24 13:00  不及格的程序员-八神  阅读(249)  评论(0编辑  收藏  举报