Login
Username:

Password:

Remember me



Lost Password?

Register now!

Sections

Who's Online
44 user(s) are online (30 user(s) are browsing Forums)

Members: 1
Guests: 43

AmigaSociety, more...

Headlines

 
  Register To Post  

« 1 (2) 3 4 5 »
Re: Tracing
Home away from home
Home away from home


See User information
@joerg
But then, if involved components didn't build with gstabs, i will be unable to see what happems even with stacktrace, right ?

For example i cookie up this based on exec doc and spotless debugger:

#include <proto/exec.h>
#include <proto/dos.h>

#include <exec/types.h>
#include <exec/interrupts.h>
#include <exec/tasks.h>

#include <dos/dos.h>

#include <stdio.h>

int32 printStack(struct Hook *hookstruct Task *taskstruct StackFrameMsg *frame)
{
      switch (
frame->State)
      {
        case 
STACK_FRAME_DECODED: {

    
            
IDOS->Printf("(%p) -> %p "frame->StackPointerframe->MemoryAddress);

            
struct DebugSymbol *symbol IDebug->ObtainDebugSymbol(frame->MemoryAddressNULL);

            if (
symbol) {
    
                if(
symbol->Type == DEBUG_SYMBOL_MODULE_STABS && symbol->SourceFileName)
                        
IDOS->Printf("[%s: line %d]: %s"symbol->SourceFileNamesymbol->SourceLineNumbersymbol->SourceFunctionName);
                else if(
symbol->SourceFunctionName)
                        
IDOS->Printf("%s"symbol->SourceFunctionName);
                else 
                        
IDOS->Printf("[%s]\n"symbol->Name);

                
IDebug->ReleaseDebugSymbol(symbol);
    
            }

        }
        break;

        case 
STACK_FRAME_INVALID_BACKCHAIN_PTR:
          
IDOS->Printf("(%p) invalid backchain pointer\n",frame->StackPointer);
          break;

        case 
STACK_FRAME_TRASHED_MEMORY_LOOP:
          
IDOS->Printf("(%p) trashed memory loop\n"frame->StackPointer);
          break;

        case 
STACK_FRAME_BACKCHAIN_PTR_LOOP:
          
IDOS->Printf("(%p) backchain pointer loop\n",frame->StackPointer);
          break;

        default:
          
IDOS->Printf("Unknown state=%lu\n"frame->State);
      }

      return 
0;  // Continue tracing.
}


int main()
{
    
struct Task *task IExec->FindTask("Workbench");

    if (
task != NULL)
    {
      
struct Hook *hook IExec->AllocSysObjectTags(ASOT_HOOKASOHOOK_EntryprintStackTAG_END);

      if (
hook != NULL)
      {
        
IExec->SuspendTask(task0);
        
uint32 result IDebug->StackTrace(taskhook);
        
IExec->RestartTask(task0);

        
IExec->FreeSysObject(ASOT_HOOKhook);
      }

    }

}


And the output are:

12/0.Work:hooksstacktrace 
(0x64da8e80) -> 0x01806544 [kernel]
(
0x64da8eb0) -> 0x0183c338 [kernel]
(
0x64da8f10) -> 0x7ff0edd8 [LIBS:workbench.library]
(
0x64da8fc0) -> 0x0185f2b4 [kernel]
(
0x64da8fd0) -> 0x0185f32c [kernel]


So for "workbench" task we had this stack trace. At lest we can see the components involved ..


Edited by kas1e on 2024/5/4 4:26:04
Join us to improve dopus5!
AmigaOS4 on youtube
Go to top
Re: Tracing
Home away from home
Home away from home


See User information
@joerg
Is for every run of CallHookPkt i should install a hook, grab stack trace, and remove hook ?

For now i have that:

https://kas1e.mikendezign.com/aos4/tra ... llhookpkt_stacktrace_v1.c

But when i run my test binary, it simply invokes one time call to CallHookPkt when reach a state of "stricmp" comparison that it's my binary i want to trace, and then nothing happens : test binary with CallHookPkt usage didn't runs, but also didn't crash , and in trace we stuck forever on SuspendTask.. right when we should obtain a stacktrace. Maybe i can't suspend process like that ? I mean:
SuspendTask(&process->pr_Task,0) ?


ps. Btw:

Quote:

I would have expected much more calls/s.
layers and graphics (for example the BackFill Hooks), intuition (incl. all BOOPSI gadgets, images and data types, Windows alpha/shape/scrolling/etc., ...), IIRC Dockies (AmiDock) as well, and a lot more in AmigaOS uses Hooks


With AmiDock's Dockies there indeed lots more CallHookPkt() happens: 250/s (while without, with pure plain system with WB loaded only 50/s).

As for other intuitions and co hooks, it surely shows me just about 50/s. If you had access old source code of OS4, will it be no NDA-breaking if you will check if for example, those gadgets and datatypes you mention do use CallHookPkt(), or, still old CallHook() ?

And interesting, that when i tried to trace for example this one:
https://www.os4coding.net/sites/default/files/ra_appwindow_0.txt (creates AppWindow hook in the ReAction window object) it counts ~500 calls to CallHookPkt(). So maybe if i not use any class when load up system, then it didn't loaded up, so those CallHookPkt() isn't active. But once i load up first time a app which use intuition hooks, then it throw massive usage of the CallHookPkt() ?

ps2: And if there is a way how we can calculate pure CallHook() usage (not CallHookPkt()) in whole system per second ? As far as i aware CallHook() were varags version of CallHookPkt(), so then finally any call to CallHook() go through CallHookPkt anyway..


Edited by kas1e on 2024/5/4 4:44:23
Edited by kas1e on 2024/5/4 4:57:21
Edited by kas1e on 2024/5/4 4:58:19
Edited by kas1e on 2024/5/4 5:34:51
Edited by kas1e on 2024/5/4 5:51:33
Edited by kas1e on 2024/5/4 5:55:28
Join us to improve dopus5!
AmigaOS4 on youtube
Go to top
Re: Tracing
Just can't stay away
Just can't stay away


See User information
@kas1e
Quote:
But when i run my test binary, it simply invokes one time call to CallHookPkt when reach a state of "stricmp" comparison that it's my binary i want to trace, and then nothing happens : test binary with CallHookPkt usage didn't runs, but also didn't crash , and in trace we stuck forever on SuspendTask.. right when we should obtain a stacktrace. Maybe i can't suspend process like that ? I mean:
SuspendTask(&process->pr_Task,0) ?
struct Process *process = (struct Process *)IExec->FindTask(NULL);
...
IExec->SuspendTask(&process->pr_Task,0);
You are suspending your own task, the one executing this code, and
uint32 result IDebug->StackTrace(&process->pr_Task,hook);
IExec->RestartTask(&process->pr_Task,0);
can't be reached


Quote:
If you had access old source code of OS4, will it be no NDA-breaking if you will check if for example, those gadgets and datatypes you mention do use CallHookPkt(), or, still old CallHook() ?
I don't have access to the sources, but using m68k libamiga.a CallHook() in PPC native code is impossible. It can only be used for emulated m68k hook functions called by emulated m68k code, only IUtility->CallHookPkt() can be used from PPC native code, checks if the hook function is PPC native (direct function call) or emulated m68k code (executing it with the m68k emulator).

Is there an OS4 PPC libamiga.a with a CallHook() function?
Would be complete nonsense (unless all it does is calling IUtility->CallHookPkt()), but OTOH I wouldn't be surprised if clib2 has something like that.

Quote:
And if there is a way how we can calculate pure CallHook() usage (not CallHookPkt()) in whole system per second ?
CallHook() is no OS function but statically linked into m68k executables from the m68k libamiga.a, some implementations of libamiga.a CallHook() are even m68k assembler.

Go to top
Re: Tracing
Home away from home
Home away from home


See User information
@joerg
Quote:

You are suspending your own task, the one executing this code, and


Damn :) But if i will remove suspend/restart, i then will be not able to correctly obtain stack trace ? (tried now with removing, crashes on IDebug->StackTrace(..) )


Quote:

Is there an OS4 PPC libamiga.a with a CallHook() function?
Would be complete nonsense (unless all it does is calling IUtility->CallHookPkt()), but OTOH I wouldn't be surprised if clib2 has something like that.


Clib2 indeed have amiga_callhook.c and amiga_callhooka.c:

https://github.com/adtools/clib2/blob/ ... rary/amiga_callhook.c#L49

https://github.com/adtools/clib2/blob/ ... ary/amiga_callhooka.c#L61

But this one compiles in only when build 68k version of clib2, for os4 it didn't (at least, as i see from Makefile's in Andrea's clib4 fork). But if i check libamiga.a from original clib2, i can see there "amiga_callhooka.o", which probabaly just an empty stabs, as code of CallHookA pure 68k asm.

Quote:

CallHook() is no OS function but statically linked into m68k executables from the m68k libamiga.a,

Right, so then we can forget about CallHook() old stuff then. Probably the reasons why i have so small amount of CallHookPkt() calls on pure WB (50/s), is that nothing were runs which open up hooking functionality of all classes,libs,etc (through, i was under opinion that when WB load up, it already uses intuition heavy).

Join us to improve dopus5!
AmigaOS4 on youtube
Go to top
Re: Tracing
Just can't stay away
Just can't stay away


See User information
@kas1e
Quote:
Clib2 indeed have amiga_callhook.c and amiga_callhooka.c:
But both with
#if (defined(__GNUC__) && !defined(__PPC__))
or
#ifndef __PPC__
The PPC clib2 libamga.a amiga_callhooka.o can only be an useless, empty object.

Go to top
Re: Tracing
Home away from home
Home away from home


See User information
@joerg
Quote:

You are suspending your own task, the one executing this code, and can't be reached


But aren't i doing this only when i am in process which had cli_commandname i point out in the argv[1], so should suspend this one instead, and not my general one ?

In other words, how to find out an task address of the process i need to trace, like by doing another FindTask ? But how to say that this is the task i need to find which had my cli_commandname ? The task name my binary have is "Background_CLI" as many other ones, so second FindTask() probably will of no help there (that why i were under impression that when i am already checked that current process is the one having my cli_command, doing suspend of this process will mean suspend this one, and not general one).

Join us to improve dopus5!
AmigaOS4 on youtube
Go to top
Re: Tracing
Not too shy to talk
Not too shy to talk


See User information
@kas1e

I can see what's going on. Your patch does indeed find the process that is calling your patched function and is a different process to your tracing process. The problem is when another process calls your function that process is the one running so it ends up suspending itself!

You will need to do some IPC I think. I've dealt with this stuff before. What I usually do is setup a MsgPort stored as global pointer in main process so it can be reachable outside it. Then in the patched function setup a Message as local static or allocated on demand. Fill it with the task ID. Send it to your main process and wait. From the main process wait on the port for messages. Perform the needed extraction, print it out then signal back. I like to use SIGF_SINGLE as it's designed for one time use. It should be cleared beforehand.

This way also avoids suspending a task as the other task will be waiting for your main one to process the information. Then it gets signalled back. Given it needs to print out a stack track regardless the latency of using IPC shouldn't bother it much.

Go to top
Re: Tracing
Home away from home
Home away from home


See User information
@Hypex
Quote:

The problem is when another process calls your function that process is the one running so it ends up suspending itself!


mm.. sounds complicated enough ! :) I mean we run the binary, so we have our own findtask(NULL) process (of main binary, in the main() ).

Then, if we run findtask(null) in the patched callhookpkt(), then we find the proccess from where this patched callhookpkt were run, right ? (because if not, how i can detect then the name of the tasks invovled in, etc).

And then, when we in this process in this patched function, should't process be not our from main(), but the one name of task from which we are taken ?

Join us to improve dopus5!
AmigaOS4 on youtube
Go to top
Re: Tracing
Not too shy to talk
Not too shy to talk


See User information
@kas1e

Quote:
mm.. sounds complicated enough ! :) I mean we run the binary, so we have our own findtask(NULL) process (of main binary, in the main() ).


The fun of library patching.

But I don't see FindTask(NULL) in your main(), I only see it in the Patched_CallHookPkt() routine.

Quote:
Then, if we run findtask(null) in the patched callhookpkt(), then we find the proccess from where this patched callhookpkt were run, right ? (because if not, how i can detect then the name of the tasks invovled in, etc).


Yes, the process that called CallHookPkt(). It would find that process in FindTask().

Quote:
And then, when we in this process in this patched function, should't process be not our from main(), but the one name of task from which we are taken ?


Yes, it would. That's where I see the issue. The process that called Patched_CallHookPkt() would end up suspending itself. Since it finds itself with FindTask(). Then passes that to SuspendTask(). It finds itself then loses itself lol.

It likely doesn't matter what context printStack() would be running in at this point. If printStack() is running on the same context as the calling process, that is while it's the running process, then that will cause trouble.

However, looking again at the code of callhookpkt_stacktrace_v1.c, this may be easier than it seems. Is this libauto as no libraries are opened? Also, where is IDebug filled in? I don't see any protos for it nor am aware of libauto able to open debug interface of Exec.

Go to top
Re: Tracing
Home away from home
Home away from home


See User information
@Hypex
Quote:

But I don't see FindTask(NULL) in your main(), I only see it in the Patched_CallHookPkt() routine.


Rigth, there is none, because i don't it :) I just point about that if it was in main, then yeah, that will be my main process, but as this FindTask(NULL) only in patched CallHookPkt, then , together with check on only my binary to trace (via cmd_CommandName), we at this point kind of sure (i were in hope) that this is the process we had, and we not need any new "findtask" for , as we already can suspend it from &process->pr_Task.

Quote:

However, looking again at the code of callhookpkt_stacktrace_v1.c, this may be easier than it seems. Is this libauto as no libraries are opened? Also, where is IDebug filled in? I don't see any protos for it nor am aware of libauto able to open debug interface of Exec.


IDebug is an Exec's thing, and yeah i use libauto: i tested by standalone binary (without patching involved) and IDebug handles well by it and stack trace working for let's say FindTask("Workbench").. But not when i put my process to trace on : it simple hang binary i want to trace+stack-trace right after first CallHookPkt() call.

Maybe when we in patched function i should obtain IDebug again ?

Join us to improve dopus5!
AmigaOS4 on youtube
Go to top
Re: Tracing
Home away from home
Home away from home


See User information
@Hypex
Ok, things start to clean up itself a bit. If i tried just this in the CallHookPkt() patching function, i then happy crash:

struct Task *task IExec->FindTask("serial.device");

    if (
task != NULL)
    {
      
struct Hook *hookstack IExec->AllocSysObjectTags(ASOT_HOOKASOHOOK_EntryprintStackTAG_END);

      if (
hookstack != NULL)
      {
        
IExec->FreeSysObject(ASOT_HOOKhookstack);
      }
    }


But when i put the same exactly code to the main , and leave patching function just pure return to original CallHookPkt, then it works.

So just setting of the Hook inside the patched CallHookPkt cause crash, not the issues with task/process/etc. And it does not matter what my actual printStack function are: i even tried it to be just an empty one.

I.e. pure set of any hook inside the patched CallHookPkt() = crash. Probably that what Joerg mean when says "Exclude own hook from patched CallHookPkt to avoid endless loop and crash" ? But then, my task is explicitly "serial.device", so not the main one ..


Edited by kas1e on 2024/5/4 11:59:05
Edited by kas1e on 2024/5/4 12:01:49
Edited by kas1e on 2024/5/4 12:04:20
Edited by kas1e on 2024/5/4 12:09:29
Edited by kas1e on 2024/5/4 12:12:43
Join us to improve dopus5!
AmigaOS4 on youtube
Go to top
Re: Tracing
Home away from home
Home away from home


See User information
@kas1e

struct Task *task IExec->FindTask("serial.device");


this is dangerous, you are now searching the task list for name, but list can change while you search. so it can crash.

you should do:

IExec->Forbid();
struct Task *task IExec->FindTask("serial.device");
IExec->Premit();


but this can also be dangerous, because you do not know if your patched is being called inside a forbid(), the permit() can break the forbid() at the wrong time. So you should first check if your inside a forbid, before you do a forbid, and a permit.

Also, if your dealing with another task, it can be unloaded from memory, before you which. So again you should not peek & poke in another tasks Task struct, unless you know you have exclusive asses to it, task struct does not have a locking mechanism, mutex/semaphore, so you most block multitasking.

If you are just comparing task pointers, and not looking inside it, you don’t need to worry about it much, but it can be a different task, then you expected, as memory is often reused in AmigaOS4, but it highly unlikely. More likely the memory will end up being used for something else.

IExec->FindTask(NULL);


does not search the list, and is therefor is safe.
no forbid, permit needed. And if you are working on yourself, you expect nothing is unloaded.


Edited by LiveForIt on 2024/5/4 13:00:59
Edited by LiveForIt on 2024/5/4 14:06:22
(NutsAboutAmiga)

Basilisk II for AmigaOS4
AmigaInputAnywhere
Excalibur
and other tools and apps.
Go to top
Re: Tracing
Home away from home
Home away from home


See User information
@LiveForIt
This all just for tests (serial.device i mean). Problem currently is seems in the fact that i set hook from hooked CallHookPkt(), and i need exclude my hook from patched CallHookPkt somehow (but can't see how can i do so by ObtainDebugSymbol() )

Join us to improve dopus5!
AmigaOS4 on youtube
Go to top
Re: Tracing
Just can't stay away
Just can't stay away


See User information
@kas1e
Quote:
struct Hook *hookstack IExec->AllocSysObjectTags(ASOT_HOOKASOHOOK_EntryprintStackTAG_END);
You shouldn't allocate memory in a patched function as that will for example break a Forbid() or Disable() state.
You can't use the IDebug functions in the patch either, maybe StackTrace() is no problem if you use IExec->DebugPrintF() instead of IDOS->Printf(), but for example ObtainDebugSymbol() which has to re-open the ELF file handle can't be used.
Getting the symbols/module name and any output, except for DebugPrintF(), has to be done in your main() task, not in a task calling a patched function.

Instead of using task/CLI names I'd use the unique PID instead, if it's a DOS process and not an exec task.
"serial.device"? If that's really serial.device (or a replacement) it's probably not a DOS process.

Go to top
Re: Tracing
Home away from home
Home away from home


See User information
@joerg

Wait, you say i can't allocate memory in the patched function, but i use before in patched function all those allocmems, char *buffers and co, with no problems ? Or by allocating memory, you mean exactly allocating memory for the hook ?

Anyway, i put allocating/deallocating of the hook for StackTrace in the main, but then, why SuspendTask() still suspend the main one, and not the one &process->pr_Task are (which by checks on cli_commandname is the one i need) ?

Strange that i can't just do that:

if(!stricmp(buffer,traced_binary)) 
                {
                        if (&
process->pr_Task != NULL)
                        {
                                if (
hookstack != NULL)
                                {
                                    
IExec->SuspendTask(&process->pr_Task,0);
                                    
IExec->RestartTask(&process->pr_Task,0);
                                }
                        }
                }


It just suspends task one time, and never do restart task. Even it if suspend my main one, why it didn't restart it after ? But then i am in the process with cli_commandname i need, so why it didn't suspend this one instead ? Or it is , just can't restart after ?

Join us to improve dopus5!
AmigaOS4 on youtube
Go to top
Re: Tracing
Quite a regular
Quite a regular


See User information
@kas1e
Maybe I don't understand the problem in the first place but I think if you're in the hooked function then you're running within the task that called the function you've replaced so whatever you do will affect the caller. If you suspend the task then it will not be run any more so the next line that would resume it won't be reached and there's nothing else to resume it. If you can't walk the stack to find the callers from the hooked function then I think what you might need to do is implement getting a stack trace in your main program and create a message port to invoke this stack trace collecting function on the task passed in the message. Then from the hooked function send the process id to the main program and wait until it replies. This will suspend the task waiting for the reply until the main program can collect the stack trace then it can resume the caller by replying to the message. This is what @Hypex proposed above if I got that correctly.

Go to top
Re: Tracing
Home away from home
Home away from home


See User information
@balaton
Right, so it means that we can only suspend/obtainstack/remove from any other task/process (not exactly from main(), but anything else which is not caller's task).

I tried simple call StackTrace() without Suspend/Restart task from the main() of Workbench task (just for tests) : and it works. But when i tried to do the same StackTrace() without Suspend/Restart from patched CallHookPkt (from the same Workbench task) i then crash and burn right at calling StackTrace() :)

Join us to improve dopus5!
AmigaOS4 on youtube
Go to top
Re: Tracing
Home away from home
Home away from home


See User information
@All
Another question:

I do have very simple test app, that it:

#include <stdio.h>
#include <stdlib.h>
#include <proto/exec.h>
#include <proto/utility.h>
#include <exec/types.h>
#include <exec/libraries.h>
#include <utility/hooks.h>

uint32 MyFunction (struct Hook *hVOID *oVOID *msg)
{
    
printf("test\n");
    return(
1);
}

int main()
{

// dynamic way:
    
struct Hook *IExec->AllocSysObjectTags(ASOT_HOOK,
        
ASOHOOK_EntryMyFunction,
        
TAG_END);

    if (
!= NULL)
    {
        
/* Use the utility library function to invoke the Hook */
        
IUtility->CallHookPkt (hNULLNULL);

        
IExec->FreeSysObject(ASOT_HOOKh);
    }
    exit(
0);
}



Now, if i install a patched CallHookPkt, find my binary name of this test case as process, and printf a DebugPrintF there (and nothing else) , then for single CallHookPkt() from my test app, i do have 100 CallHookPkts runs in whole system.

Why not a single one ? Is it mean that one my call, involve 100 other ones in the deep of the system (DOS, Intuition, etc ?)

Join us to improve dopus5!
AmigaOS4 on youtube
Go to top
Re: Tracing
Home away from home
Home away from home


See User information
@kas1e

Lots of boiler plate there. wont it be easier to do.

uint32 ret = MyFunction (NULL, NULL, NULL) ;

LOL

(NutsAboutAmiga)

Basilisk II for AmigaOS4
AmigaInputAnywhere
Excalibur
and other tools and apps.
Go to top
Re: Tracing
Home away from home
Home away from home


See User information
@LiveForIt
Right, almost answer on my question :)

Join us to improve dopus5!
AmigaOS4 on youtube
Go to top

  Register To Post
« 1 (2) 3 4 5 »

 




Currently Active Users Viewing This Thread: 1 ( 0 members and 1 Anonymous Users )




Powered by XOOPS 2.0 © 2001-2023 The XOOPS Project