Run-time debugger in Blackbox Component Builder
-
- Posts: 262
- Joined: Tue Sep 17, 2013 6:50 am
Re: Run-time debugger in Blackbox Component Builder
Syntax highlighting is an editor feature.
It would require a special editor for module source texts
as opposed to the general purpose text editor of BlackBox.
It has been done in ETH A2 Oberon, for example, and in
more traditional IDEs such as NetBeans and Eclipse.
While such an editor may be helpful indeed, I wouldn't consider
it an alternative for a runtime debugger, which could be
quite helpful in understanding existing complex programs
such as the BlackBox framework itself.
Since ominc did not include it in their original BlackBox distribution,
it is probably more a prototype of such a debugger. That's why I was
asking about known problems or limitations.
- Josef
It would require a special editor for module source texts
as opposed to the general purpose text editor of BlackBox.
It has been done in ETH A2 Oberon, for example, and in
more traditional IDEs such as NetBeans and Eclipse.
While such an editor may be helpful indeed, I wouldn't consider
it an alternative for a runtime debugger, which could be
quite helpful in understanding existing complex programs
such as the BlackBox framework itself.
Since ominc did not include it in their original BlackBox distribution,
it is probably more a prototype of such a debugger. That's why I was
asking about known problems or limitations.
- Josef
Re: Run-time debugger in Blackbox Component Builder
I have managed to run this debugger on BlackBox build 64. Debugger is running in another process. It can show loaded modules of debugged process, show global variables of some module of debugged process and heap objects. Traps are redirected to debugger.Josef Templ wrote:Does this debugger work reliably?
Is it in a shape such that it could be included in the
center distribution?
Any known bugs or limitations?
Anything like a docu?
- Josef
Step debugging are using in following way:
1. Open source code of module to be debugged
2. Put caret to line (do not select anything) and set breakpoint by menu Debug -> Breakpoint 1, 2, 3. Menu item became checked
3. When breakpoint is triggered trap will be shown and stopped position will be selected
4. Step over/into can be used: trap and selected position will be updated
Some documentation is included.
Debugger need to be adapted for Kernel UTF-8 changes. Way of transferring of modList pointer to debugger is not working on Windows 8.1. Following code in Kernel.Init are used for this, but EBX became 0 when debugger handles debug string. Probably this register is used inside of OutputDebugStringW. I changed register to EDI to make it working, but it may also stop working in future Windows versions, another way of transferring modList pointer is required.
Code: Select all
S.PUTREG(ML, S.ADR(modList));
WinApi.OutputDebugStringW("BlackBox started");
- Attachments
-
- RemDebug.7z
- (151.07 KiB) Downloaded 447 times
Re: Run-time debugger in Blackbox Component Builder
Using RemDebug in theory any BlackBox made application with Kernel linked may be debugged.
-
- Posts: 262
- Joined: Tue Sep 17, 2013 6:50 am
Re: Run-time debugger in Blackbox Component Builder
Thanks for uploading the revised RemDebug packageX512 wrote: Debugger need to be adapted for Kernel UTF-8 changes. Way of transferring of modList pointer to debugger is not working on Windows 8.1. Following code in Kernel.Init are used for this, but EBX became 0 when debugger handles debug string. Probably this register is used inside of OutputDebugStringW. I changed register to EDI to make it working, but it may also stop working in future Windows versions, another way of transferring modList pointer is required.Code: Select all
S.PUTREG(ML, S.ADR(modList)); WinApi.OutputDebugStringW("BlackBox started");
and for the excellent analysis.
Under Win10 I cannot reproduce the problem with EBX,
which is surprising because it should be similar to Win8.1.
Anyway, passing modList via a register is highly questionable indeed.
In addition, I thought that EBX is 'callee' saved, so it should not be changed at all
without restoring it.
A more portable approach may be to pass modList as part of
OutputDebugStringW("BlackBox started"), e.g. "BlackBox started [modList=xxxxxxxxx]"
but it requires an int-to-string conversion in Kernel.
I haven't found any other way of passing an address from the target to
the debugger so far.
- Josef
-
- Posts: 262
- Joined: Tue Sep 17, 2013 6:50 am
Re: Run-time debugger in Blackbox Component Builder
I just noticed that EBX is not really changed by setting it to modList
because it already had this value when the module body was started.
It is an implicit parameter passed from the main entry point to the module Kernel.
Since it is not used in code generation by the compiler, except for nested procedures
I think, it is a very natural choice for passing information to the debugger.
@X512: are you sure that it does not work under Win 8.1?
- Josef
because it already had this value when the module body was started.
It is an implicit parameter passed from the main entry point to the module Kernel.
Since it is not used in code generation by the compiler, except for nested procedures
I think, it is a very natural choice for passing information to the debugger.
@X512: are you sure that it does not work under Win 8.1?
- Josef
- DGDanforth
- Posts: 59
- Joined: Tue Sep 17, 2013 1:16 am
- Location: Palo Alto, CA, U.S.A.
- Contact:
Re: Run-time debugger in Blackbox Component Builder
I simply change the definition of Ctrl-K to be
"Compile And Unload" "K" "DevCompiler.CompileAndUnload" "TextCmds.FocusGuard"
Re: Run-time debugger in Blackbox Component Builder
In theory EBX register may be allocated by compiler for expression evaluation. Also value passed to debugger is not modList, but pointer to modList. Global variables modList, root and baseStack are used by debugger as single structure and pointer to modList is pointer to that structure.Josef Templ wrote:I just noticed that EBX is not really changed by setting it to modList
because it already had this value when the module body was started.
It is an implicit parameter passed from the main entry point to the module Kernel.
Yes. I made a simple test to inspect what happens with registers during call of OutputDebugString:Josef Templ wrote:@X512: are you sure that it does not work under Win 8.1?
Kernel.Init
Code: Select all
S.PUTREG(0, 12345678H);
S.PUTREG(1, 12345678H);
S.PUTREG(2, 12345678H);
S.PUTREG(3, 12345678H);
S.PUTREG(6, 12345678H);
S.PUTREG(7, 12345678H);
WinApi.OutputDebugStringW("BlackBox started");
Code: Select all
IF string = "BlackBox started" THEN
context.ContextFlags := WinApi.CONTEXT_INTEGER;
res := WinApi.GetThreadContext(threadHandle, context); ASSERT(res # 0);
Log.String("EAX = "); Log.IntForm(context.Eax, 16, 9, "0", FALSE); Log.String("H"); Log.Ln;
Log.String("ECX = "); Log.IntForm(context.Ecx, 16, 9, "0", FALSE); Log.String("H"); Log.Ln;
Log.String("EDX = "); Log.IntForm(context.Edx, 16, 9, "0", FALSE); Log.String("H"); Log.Ln;
Log.String("EBX = "); Log.IntForm(context.Ebx, 16, 9, "0", FALSE); Log.String("H"); Log.Ln;
Log.String("ESI = "); Log.IntForm(context.Esi, 16, 9, "0", FALSE); Log.String("H"); Log.Ln;
Log.String("EDI = "); Log.IntForm(context.Edi, 16, 9, "0", FALSE); Log.String("H"); Log.Ln;
kernelAdr := 0;
END;
Code: Select all
EAX = 00023FC60H
ECX = 000000002H
EDX = 000000000H
EBX = 000000000H
ESI = 0005C3259H
EDI = 012345678H
Tested system is Windows 8.1, 32 bit.
-
- Posts: 262
- Joined: Tue Sep 17, 2013 6:50 am
Re: Run-time debugger in Blackbox Component Builder
Since EDI is not guaranteed to be unchanged either
the only portable approach would be to
pass kernelAdr as part of the debug string, right?
WinApi.OutputDebugStringW("BlackBox started [kernelAdr=1234567]";
No big problem, but requires some string handling.
- Josef
the only portable approach would be to
pass kernelAdr as part of the debug string, right?
WinApi.OutputDebugStringW("BlackBox started [kernelAdr=1234567]";
No big problem, but requires some string handling.
- Josef
- Ivan Denisov
- Posts: 362
- Joined: Tue Sep 17, 2013 12:21 am
- Location: Krasnoyarsk, Russia
Re: Run-time debugger in Blackbox Component Builder
Is there version of DevRemDebug which works with Windows 10 correctly?
- Ivan Denisov
- Posts: 362
- Joined: Tue Sep 17, 2013 12:21 am
- Location: Krasnoyarsk, Russia
Re: Run-time debugger in Blackbox Component Builder
I checked suggested method and it works.
I modified the kernel.
And in DevRemDebug
I modified the kernel.
Code: Select all
S.PUTREG(ML, S.ADR(modList));
IntToString(S.ADR(modList), trans);
str := "BlackBox started [-----------------]";
FOR i:= 0 TO LEN(trans$)-1 DO
str[18 + i] := trans[i]
END;
WinApi.OutputDebugStringW(str);
Code: Select all
| WinApi.OUTPUT_DEBUG_STRING_EVENT:
IF (event.u.DebugString.fUnicode = 0) & (event.dwProcessId = procId) THEN
GetName(SYSTEM.VAL(INTEGER, event.u.DebugString.lpDebugStringData), string);
Log.String(string); Log.Ln; (* DIA *)
string[16] := 0X;
IF string$ = "BlackBox started" THEN
Log.String(string); Log.Ln; (* DIA *)
context.ContextFlags := WinApi.CONTEXT_INTEGER;
res := WinApi.GetThreadContext(threadHandle, context); ASSERT(res # 0);
IF string[17] = "[" THEN
i := 18;
WHILE (string[i] # "-") & (string[i] # "]") DO
kernelAddressString[i - 18] := string[i];
INC(i);
END;
kernelAddressString[i - 18] := 0X;
Log.String(kernelAddressString); Log.Ln; (* DIA *)
Strings.StringToInt(kernelAddressString, kernelAdr, i);
ELSE
kernelAdr := context.(*Ebx*)Edi;
END;
Log.Int(kernelAdr); Log.Ln; (* DIA *)
END;
END