Fixed a potential strict aliasing bug.
[AROS.git] / workbench / c / StackSnoop.c
blobe172b146a97c233b278eff94593dd98b7be84539
1 /*
2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 Lang: English
7 */
9 #include <exec/exec.h>
10 #include <exec/execbase.h>
11 #include <exec/tasks.h>
12 #include <exec/rawfmt.h>
13 #include <dos/dos.h>
14 #include <proto/exec.h>
15 #include <proto/dos.h>
16 #include <proto/debug.h>
17 #include <proto/alib.h>
19 #include <string.h>
21 #define ARG_TEMPLATE "TASK/K,DEBUG/S"
23 #define ARG_TASK 0
24 #define ARG_DEBUG 1
25 #define NUM_ARGS 2
27 static struct RDArgs *MyArgs;
28 static IPTR Args[NUM_ARGS];
29 static char s[256];
31 static UBYTE outbuffer[20000];
32 static LONG outbuffer_size;
34 static void Cleanup(char *msg)
36 if (msg)
37 Printf("stacksnoop: %s\n",msg);
39 if (MyArgs) FreeArgs(MyArgs);
42 static ULONG GetArguments(void)
44 if (!(MyArgs = ReadArgs(ARG_TEMPLATE,Args,0)))
46 Fault(IoErr(),0,s,255);
47 Cleanup(s);
48 return RETURN_WARN;
50 return 0;
53 static int out (const UBYTE * fmt, ...)
55 va_list ap;
56 int result;
58 va_start (ap, fmt);
60 VNewRawDoFmt(fmt, RAWFMTFUNC_STRING, &outbuffer[outbuffer_size], ap);
61 result = strlen(&outbuffer[outbuffer_size]);
63 if (Args[ARG_DEBUG])
64 KPutStr(&outbuffer[outbuffer_size]);
66 outbuffer_size += result;
68 va_end (ap);
70 return result;
74 static void CheckTaskStack(struct Task *task)
76 UBYTE *startcheck, *endcheck;
77 LONG stacksize, stackinc, unusedstack = 0;
79 stacksize = (LONG)( ((UBYTE *)task->tc_SPUpper) - ((UBYTE *)task->tc_SPLower) );
81 #if AROS_STACK_GROWS_DOWNWARDS
82 startcheck = (UBYTE *)task->tc_SPLower;
83 endcheck = ((UBYTE *)task->tc_SPUpper) - 1;
84 stackinc = 1;
85 #else
86 startcheck = ((UBYTE *)task->tc_SPUpper) - 1;
87 endcheck = (UBYTE *)task->tc_SPLower;
88 stackinc = -1;
89 #endif
91 for(; startcheck != endcheck; startcheck += stackinc)
93 if (*startcheck != 0xE1) break;
94 unusedstack++;
97 out("Task %x (%25s) Stack Size =%6d, Left =%6d, Used %s%6d%s\n",
98 task,
99 task->tc_Node.ln_Name ? task->tc_Node.ln_Name : "<NONAME>",
100 stacksize,
101 unusedstack,
102 ((stacksize - unusedstack) < stacksize) ? "=" : ">",
103 stacksize - unusedstack,
104 (unusedstack < 512) ? ": Needs more stack!!!!!!!!!" : "");
107 static void Action(void)
109 struct Task *task;
110 WORD i;
112 Disable();
114 out("\n------------------------------------------------------------------------------\n\n");
116 task = (struct Task *)SysBase->TaskReady.lh_Head;
117 for(i = 0; i < 2;i++)
119 while(task->tc_Node.ln_Succ)
121 CheckTaskStack(task);
123 task = (struct Task *)task->tc_Node.ln_Succ;
124 } /* while(task->tc_Node.ln_Succ) */
126 task = (struct Task *)SysBase->TaskWait.lh_Head;
128 } /* for(i = 0; i < 2;i++) */
129 out("\n");
130 CheckTaskStack(FindTask(NULL));
131 out("\n------------------------------------------------------------------------------\n\n");
133 Enable();
135 PutStr(outbuffer);
138 ULONG __nocommandline = 1;
140 int main(void)
142 int rc;
144 rc = GetArguments();
145 if (rc)
146 return rc;
148 Action();
149 Cleanup(0);
150 return 0;