exec.library: place list of MemHeaderAllocatorCtx into IntExecBase
[AROS.git] / workbench / c / StackSnoop.c
blobfcfae87df6f81164f843e0e05d717a72c073aeb7
1 /*
2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 Lang: English
7 */
9 /******************************************************************************
12 NAME
14 StackSnoop
16 SYNOPSIS
18 (N/A)
20 LOCATION
24 FUNCTION
26 Prints a list of tasks with their stack usage.
28 INPUTS
30 RESULT
32 NOTES
34 EXAMPLE
36 BUGS
38 SEE ALSO
40 INTERNALS
42 HISTORY
44 ******************************************************************************/
46 #include <exec/exec.h>
47 #include <exec/execbase.h>
48 #include <exec/tasks.h>
49 #include <exec/rawfmt.h>
50 #include <dos/dos.h>
51 #include <proto/exec.h>
52 #include <proto/dos.h>
53 #include <proto/debug.h>
54 #include <proto/alib.h>
56 #include <string.h>
58 #define ARG_TEMPLATE "TASK/K,DEBUG/S"
60 #define ARG_TASK 0
61 #define ARG_DEBUG 1
62 #define NUM_ARGS 2
64 static struct RDArgs *MyArgs;
65 static IPTR Args[NUM_ARGS];
66 static char s[256];
68 static UBYTE outbuffer[20000];
69 static LONG outbuffer_size;
71 static void Cleanup(char *msg)
73 if (msg)
74 Printf("stacksnoop: %s\n",msg);
76 if (MyArgs) FreeArgs(MyArgs);
79 static ULONG GetArguments(void)
81 if (!(MyArgs = ReadArgs(ARG_TEMPLATE,Args,0)))
83 Fault(IoErr(),0,s,255);
84 Cleanup(s);
85 return RETURN_WARN;
87 return 0;
90 static int out (const UBYTE * fmt, ...)
92 va_list ap;
93 int result;
95 va_start (ap, fmt);
97 VNewRawDoFmt(fmt, RAWFMTFUNC_STRING, &outbuffer[outbuffer_size], ap);
98 result = strlen(&outbuffer[outbuffer_size]);
100 if (Args[ARG_DEBUG])
101 KPutStr(&outbuffer[outbuffer_size]);
103 outbuffer_size += result;
105 va_end (ap);
107 return result;
111 static void CheckTaskStack(struct Task *task)
113 UBYTE *startcheck, *endcheck;
114 LONG stacksize, stackinc, unusedstack = 0;
116 stacksize = (LONG)( ((UBYTE *)task->tc_SPUpper) - ((UBYTE *)task->tc_SPLower) );
118 #if AROS_STACK_GROWS_DOWNWARDS
119 startcheck = (UBYTE *)task->tc_SPLower;
120 endcheck = ((UBYTE *)task->tc_SPUpper) - 1;
121 stackinc = 1;
122 #else
123 startcheck = ((UBYTE *)task->tc_SPUpper) - 1;
124 endcheck = (UBYTE *)task->tc_SPLower;
125 stackinc = -1;
126 #endif
128 for(; startcheck != endcheck; startcheck += stackinc)
130 if (*startcheck != 0xE1) break;
131 unusedstack++;
134 out("Task %x (%25s) Stack Size =%6d, Left =%6d, Used %s%6d%s\n",
135 task,
136 task->tc_Node.ln_Name ? task->tc_Node.ln_Name : "<NONAME>",
137 stacksize,
138 unusedstack,
139 ((stacksize - unusedstack) < stacksize) ? "=" : ">",
140 stacksize - unusedstack,
141 (unusedstack < 512) ? ": Needs more stack!!!!!!!!!" : "");
144 static void Action(void)
146 struct Task *task;
147 WORD i;
149 Disable();
151 out("\n------------------------------------------------------------------------------\n\n");
153 task = (struct Task *)SysBase->TaskReady.lh_Head;
154 for(i = 0; i < 2;i++)
156 while(task->tc_Node.ln_Succ)
158 CheckTaskStack(task);
160 task = (struct Task *)task->tc_Node.ln_Succ;
161 } /* while(task->tc_Node.ln_Succ) */
163 task = (struct Task *)SysBase->TaskWait.lh_Head;
165 } /* for(i = 0; i < 2;i++) */
166 out("\n");
167 CheckTaskStack(FindTask(NULL));
168 out("\n------------------------------------------------------------------------------\n\n");
170 Enable();
172 PutStr(outbuffer);
175 ULONG __nocommandline = 1;
177 int main(void)
179 int rc;
181 rc = GetArguments();
182 if (rc)
183 return rc;
185 Action();
186 Cleanup(0);
187 return 0;