comparison src/nucleus/erc.c @ 0:92470e5d0b9e

src: partial import from FC Selenite
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 15 May 2020 01:28:16 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:92470e5d0b9e
1 /*************************************************************************/
2 /* */
3 /* Copyright Mentor Graphics Corporation 2002 */
4 /* All Rights Reserved. */
5 /* */
6 /* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS */
7 /* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS */
8 /* SUBJECT TO LICENSE TERMS. */
9 /* */
10 /*************************************************************************/
11
12 /*************************************************************************/
13 /* */
14 /* FILE NAME VERSION */
15 /* */
16 /* erc.c Nucleus PLUS 1.14 */
17 /* */
18 /* COMPONENT */
19 /* */
20 /* ER - Error Management */
21 /* */
22 /* DESCRIPTION */
23 /* */
24 /* This file contains the core routines for the Error management */
25 /* component. */
26 /* */
27 /* DATA STRUCTURES */
28 /* */
29 /* None */
30 /* */
31 /* FUNCTIONS */
32 /* */
33 /* ERC_System_Error System error function */
34 /* ERC_Assert System assertion routine */
35 /* */
36 /* DEPENDENCIES */
37 /* */
38 /* tc_defs.h Thread control definitions */
39 /* er_extr.h Error handling functions */
40 /* */
41 /* HISTORY */
42 /* */
43 /* DATE REMARKS */
44 /* */
45 /* 03-01-1993 Created initial version 1.0 */
46 /* 04-19-1993 Verified version 1.0 */
47 /* 03-01-1994 Modified copyright notice, */
48 /* resulting in version 1.1 */
49 /* */
50 /* 03-18-1994 Verified version 1.1 */
51 /* 04-17-1996 updated to version 1.2 */
52 /* 03-24-1998 Released version 1.3. */
53 /* 11-24-1998 Added ERC_Assert routine. */
54 /* 03-26-1999 Released 1.11m (new release */
55 /* numbering scheme) */
56 /* 04-07-1999 Release 1.11mA */
57 /* 04-17-2002 Released version 1.13m */
58 /* 11-07-2002 Released version 1.14 */
59 /*************************************************************************/
60 #define NU_SOURCE_FILE
61
62 #ifdef NU_ERROR_STRING
63 #include <stdio.h> /* Standard I/O functions */
64 #endif
65 #include "tc_defs.h" /* Thread control constants */
66 #include "er_extr.h" /* Error handling functions */
67
68 #ifdef NU_DEBUG_MEMORY
69
70 #include "er_defs.h" /* Error management structures */
71 #include "dm_extr.h" /* Memory management */
72 #include "ncl\inc\string.h" /* memcmp & memcpy functions */
73 #include "ncl\inc\nu_ncl.h" /* memcmp & memcpy functions */
74
75 extern NU_MEMORY_POOL NU_DEBUG_POOL;
76 extern const UINT8 ERD_MemoryAllocationHead[];
77 extern const UINT8 ERD_MemoryAllocationFoot[];
78 extern ER_DEBUG_ALLOCATION *ERD_RecentAllocation;
79
80 extern UINT32 ERD_AllocationCount;
81 extern UINT32 ERD_AllocationSequenceCounter;
82 extern UINT32 ERD_TotalMemoryAllocated;
83 extern UINT32 ERD_TotalMemoryAllocations;
84 extern UINT32 ERD_MaxTotalMemoryAllocated;
85 extern UINT32 ERD_MaxTotalMemoryAllocations;
86
87 #endif /* NU_DEBUG_MEMORY */
88
89
90 /* Define external inner-component global data references. */
91
92 extern INT ERD_Error_Code;
93
94 #ifdef NU_ERROR_STRING
95 extern CHAR ERD_Error_String[];
96 #endif
97
98 #ifdef NU_DEBUG
99 extern UNSIGNED ERD_Assert_Count;
100 #endif
101
102
103 /* Define direct access to a thread component variable. */
104
105 extern VOID *TCD_Current_Thread;
106
107 /*************************************************************************/
108 /* */
109 /* FUNCTION */
110 /* */
111 /* ERC_System_Error */
112 /* */
113 /* DESCRIPTION */
114 /* */
115 /* This function processes system errors detected by various */
116 /* system components. Typically an error of this type is */
117 /* considered fatal. */
118 /* */
119 /* CALLED BY */
120 /* */
121 /* Various Components */
122 /* */
123 /* CALLS */
124 /* */
125 /* None */
126 /* */
127 /* INPUTS */
128 /* */
129 /* error_code Code of detected system error*/
130 /* */
131 /* OUTPUTS */
132 /* */
133 /* None */
134 /* */
135 /* HISTORY */
136 /* */
137 /* DATE REMARKS */
138 /* */
139 /* 03-01-1993 Created initial version 1.0 */
140 /* 04-19-1993 Verified version 1.0 */
141 /* */
142 /*************************************************************************/
143 VOID ERC_System_Error(INT error_code)
144 {
145 #ifdef NU_ERROR_STRING
146 INT i;
147 CHAR *pointer;
148 CHAR name[NU_MAX_NAME+1];
149 #endif
150
151 NU_SUPERV_USER_VARIABLES
152
153 /* Switch to supervisor mode */
154 NU_SUPERVISOR_MODE();
155
156 /* First place the error code into the global variable. */
157 ERD_Error_Code = error_code;
158
159 #ifdef NU_ERROR_STRING
160 /* Build string that corresponds to the error. */
161 switch(error_code)
162 {
163
164 case NU_ERROR_CREATING_TIMER_HISR:
165
166 /* Build string that indicates an error occurred creating the timer
167 HISR. */
168 sprintf(ERD_Error_String,"%s\n", "Error Creating Timer HISR");
169 break;
170
171 case NU_ERROR_CREATING_TIMER_TASK:
172
173 /* Build string that indicates an error occurred creating the timer
174 Task. */
175 sprintf(ERD_Error_String,"%s\n", "Error Creating Timer Task");
176 break;
177
178 case NU_STACK_OVERFLOW:
179
180 /* Build string that indicates a stack overflow occurred. */
181 name[NU_MAX_NAME] = (CHAR) 0;
182 pointer = (((TC_TCB *) TCD_Current_Thread) -> tc_name);
183 for (i = 0; i < NU_MAX_NAME; i++)
184 name[i] = *pointer++;
185 sprintf(ERD_Error_String,"%s %s\n", "Stack Overflow in task/HISR: ",
186 name);
187 break;
188
189
190 case NU_UNHANDLED_INTERRUPT:
191
192 /* Build string that indicates an error occurred because of an
193 unhandled interrupt. */
194 sprintf(ERD_Error_String,"%s\n", "Unhandled interrupt error");
195 break;
196 }
197 #endif
198
199 /* This function cannot return, since the error is fatal. */
200 while(1)
201 {
202 }
203
204 /* No need to return to user mode because of the infinite loop. */
205 /* Returning to user mode will cause warnings with some compilers. */
206 }
207
208 #ifdef NU_DEBUG_MEMORY
209
210 /*************************************************************************/
211 /* */
212 /* FUNCTION */
213 /* */
214 /* ERC_Memory_To_Debug */
215 /* */
216 /* DESCRIPTION */
217 /* */
218 /* This function returns a pointer to the ER_DEBUG_ALLOCATION that */
219 /* contains the memory allocation specified by the caller (target). */
220 /* */
221 /* CALLED BY */
222 /* */
223 /* ERC_Deallocate_Memory */
224 /* */
225 /* CALLS */
226 /* */
227 /* memcmp (CLIB_memcmp) */
228 /* ERC_System_Error */
229 /* */
230 /* INPUTS */
231 /* */
232 /* target memory allocation to find */
233 /* */
234 /* OUTPUTS */
235 /* */
236 /* ER_DEBUG_ALLOCATION ER_DEBUG_ALLOCATION that contains*/
237 /* target. */
238 /* */
239 /* HISTORY */
240 /* */
241 /* DATE REMARKS */
242 /* */
243 /*************************************************************************/
244 static ER_DEBUG_ALLOCATION *ERC_Memory_To_Debug(VOID *target)
245 {
246 INT dataOffset;
247 ER_DEBUG_ALLOCATION *walk;
248 ER_DEBUG_ALLOCATION *to_find;
249
250 dataOffset = (INT)(((ER_DEBUG_ALLOCATION *)0)->data);
251 to_find = (ER_DEBUG_ALLOCATION *)(((UNSIGNED_CHAR *)target) - dataOffset);
252
253 /* Invalid pointer, report no match found */
254 if((target == NULL) && (to_find == NULL))
255 return(NULL);
256
257 for (walk = ERD_RecentAllocation; ((walk != to_find) && (walk != NULL));
258 walk = walk->prev);
259
260 /* if no match was found */
261 if (walk != NULL)
262 {
263 /* Has the "HEAD" or "FOOT" been disturbed by a rouge pointer? */
264 if (memcmp((void *)ERD_MemoryAllocationHead,(void *)walk->head,4) != 0)
265 ERC_System_Error(NU_MEMORY_CORRUPT);
266 if (memcmp((void *)ERD_MemoryAllocationFoot,(void *)&(walk->data[walk->size]),4) != 0)
267 ERC_System_Error(NU_MEMORY_CORRUPT);
268 }
269
270 return(walk);
271 }
272
273 /*************************************************************************/
274 /* */
275 /* FUNCTION */
276 /* */
277 /* ERC_Remove_Debug_Allocation */
278 /* */
279 /* DESCRIPTION */
280 /* */
281 /* This function removes an ER_DEBUG_ALLOCATION from the linked list*/
282 /* */
283 /* CALLED BY */
284 /* */
285 /* ERC_Deallocate_Memory */
286 /* */
287 /* CALLS */
288 /* */
289 /* none */
290 /* */
291 /* INPUTS */
292 /* */
293 /* target ER_DEBUG_ALLOCATION to remove */
294 /* */
295 /* OUTPUTS */
296 /* */
297 /* STATUS status of the operation */
298 /* */
299 /* HISTORY */
300 /* */
301 /* DATE REMARKS */
302 /* */
303 /*************************************************************************/
304 static STATUS ERC_Remove_Debug_Allocation(ER_DEBUG_ALLOCATION *target)
305 {
306 ER_DEBUG_ALLOCATION *walk;
307
308 if (target == NULL)
309 return(NU_INVALID_POINTER);
310
311 /* If the list is empty nothing can be removed! */
312 if (ERD_RecentAllocation == NULL)
313 return(NU_EMPTY_DEBUG_ALLOCATION_LIST);
314
315 /* If there is only one item on the list. */
316 if (ERD_RecentAllocation->prev == NULL)
317 {
318 /* If the only item on the list is the one to be removed...*/
319 if (ERD_RecentAllocation == target)
320 {
321 ERD_RecentAllocation = NULL;
322 return(NU_SUCCESS);
323 }
324 else
325 return(NU_INVALID_DEBUG_ALLOCATION);
326 }
327
328 if (ERD_RecentAllocation == target)
329 {
330 ERD_RecentAllocation->prev = target->prev;
331 return(NU_SUCCESS);
332 }
333
334 /* Walk the entire list until walk->prev is the target. */
335 walk = ERD_RecentAllocation;
336 while (NU_TRUE)
337 {
338 if (walk->prev == target)
339 break;
340 if (walk->prev == NULL)
341 break;
342 walk = walk->prev;
343 }
344
345 /* target is last item on the list */
346 if (walk->prev == target)
347 {
348 walk->prev = target->prev;
349 return(NU_SUCCESS);
350 }
351 return(NU_INVALID_DEBUG_ALLOCATION);
352 }
353
354 /*************************************************************************/
355 /* */
356 /* FUNCTION */
357 /* */
358 /* ERC_Append_Debug_Allocation */
359 /* */
360 /* DESCRIPTION */
361 /* */
362 /* This function appends an ER_DEBUG_ALLOCATION to the linked list. */
363 /* */
364 /* CALLED BY */
365 /* */
366 /* ERC_Allocate_Memory */
367 /* */
368 /* CALLS */
369 /* */
370 /* none */
371 /* */
372 /* INPUTS */
373 /* */
374 /* new_guy ER_DEBUG_ALLOCATION to append */
375 /* */
376 /* OUTPUTS */
377 /* */
378 /* STATUS status of the operation */
379 /* */
380 /* HISTORY */
381 /* */
382 /* DATE REMARKS */
383 /* */
384 /*************************************************************************/
385 static STATUS ERC_Append_Debug_Allocation(ER_DEBUG_ALLOCATION *new_guy)
386 {
387
388 /* Either this is the first ER_DEBUG_ALLOCATION ever to be appended
389 or this is the first on a list that shrank to 0 element. */
390 if (ERD_AllocationCount == 0)
391 {
392 ERD_RecentAllocation = new_guy;
393 ERD_RecentAllocation->prev = NULL;
394 }
395 else
396 {
397 new_guy->prev = ERD_RecentAllocation;
398 ERD_RecentAllocation = new_guy;
399 }
400
401 return(NU_SUCCESS);
402 }
403
404 /*************************************************************************/
405 /* */
406 /* FUNCTION */
407 /* */
408 /* ERC_Allocate_Memory */
409 /* */
410 /* DESCRIPTION */
411 /* */
412 /* This function tracks additional information regarding the memory */
413 /* allocation */
414 /* */
415 /* CALLED BY */
416 /* */
417 /* Application */
418 /* */
419 /* CALLS */
420 /* */
421 /* ERC_Append_Debug_Allocation */
422 /* DMCE_Allocate_Memory */
423 /* memcpy */
424 /* */
425 /* INPUTS */
426 /* */
427 /* pool_ptr Memory pool pointer */
428 /* return_pointer Pointer to the destination */
429 /* memory pointer */
430 /* size Number of bytes requested */
431 /* suspend Suspension option if full */
432 /* */
433 /* OUTPUTS */
434 /* */
435 /* NU_SUCCESS If service is successful */
436 /* NU_NO_MEMORY Memory not available */
437 /* NU_TIMEOUT If timeout on service */
438 /* NU_POOL_DELETED If memory pool deleted */
439 /* during suspension */
440 /* */
441 /* HISTORY */
442 /* */
443 /* DATE REMARKS */
444 /* */
445 /*************************************************************************/
446 STATUS ERC_Allocate_Memory(NU_MEMORY_POOL *pool_ptr, VOID **ptr,
447 UNSIGNED size, UNSIGNED suspend,
448 unsigned long line, const char* file)
449 {
450 ER_DEBUG_ALLOCATION **debug_ptr;
451 STATUS status = NU_SUCCESS;
452
453 /* If the allocation is not from the pool specified in the
454 NU_DEBUG_POOL macro then allocate memory normally (no meta-data) */
455 if(&NU_DEBUG_POOL != pool_ptr)
456 return(DMCE_Allocate_Memory(pool_ptr, ptr, size, suspend));
457
458 /* This call allocates memory for a structure that will contain the
459 users data and the meta-data used to find memory problems */
460 status = DMCE_Allocate_Memory(pool_ptr, ptr,
461 (sizeof(ER_DEBUG_ALLOCATION) + size + 4), suspend);
462 if (status != NU_SUCCESS)
463 return status;
464
465 /* From here out, debug_ptr is used because it is typed. In the end
466 ptr will be set to point to debug_ptr->data, where the user will
467 put the data. */
468 debug_ptr = (ER_DEBUG_ALLOCATION **)ptr;
469
470 /* Record file and line where the application made the allocation */
471 (*debug_ptr)->line = line;
472 (*debug_ptr)->file = file;
473
474 /* Set "HEAD" and "FOOT" boundary markers */
475 memcpy((*debug_ptr)->head,ERD_MemoryAllocationHead,4);
476 memcpy(&((*debug_ptr)->data[size]),ERD_MemoryAllocationFoot,4);
477
478 /* Record the size */
479 (*debug_ptr)->size = size;
480
481 /* This links debug_ptr to a linked list that holds all the
482 ER_DEBUG_ALLOCATION structures. */
483 ERC_Append_Debug_Allocation((*debug_ptr));
484
485 (*debug_ptr)->AllocSequenceCounter = ERD_AllocationSequenceCounter++;
486
487 ERD_TotalMemoryAllocated += size;
488 ERD_TotalMemoryAllocations++;
489 ERD_AllocationCount++;
490
491 if (ERD_MaxTotalMemoryAllocated < ERD_TotalMemoryAllocated)
492 ERD_MaxTotalMemoryAllocated = ERD_TotalMemoryAllocated;
493 if (ERD_MaxTotalMemoryAllocations < ERD_TotalMemoryAllocations)
494 ERD_MaxTotalMemoryAllocations = ERD_TotalMemoryAllocations;
495
496 /* Return pointer to the data field of debug allocation by reference */
497 (*ptr) = (*debug_ptr)->data;
498 return(status);
499 }
500
501 /*************************************************************************/
502 /* */
503 /* FUNCTION */
504 /* */
505 /* ERC_Deallocate_Memory */
506 /* */
507 /* DESCRIPTION */
508 /* */
509 /* This function tracks additional information regarding the memory */
510 /* deallocation. */
511 /* */
512 /* CALLED BY */
513 /* */
514 /* Application */
515 /* */
516 /* CALLS */
517 /* */
518 /* ERC_Memory_To_Debug */
519 /* ERC_Remove_Debug_Allocation */
520 /* DMCE_Deallocate_Memory */
521 /* */
522 /* INPUTS */
523 /* */
524 /* ptr Pointer to dynamic memory */
525 /* */
526 /* OUTPUTS */
527 /* */
528 /* NU_SUCCESS */
529 /* NU_INVALID_POINTER Returned when ptr is null or */
530 /* when there is no */
531 /* corresponding */
532 /* ER_DEBUG_ALLOCATION */
533 /* */
534 /* HISTORY */
535 /* */
536 /* DATE REMARKS */
537 /* */
538 /*************************************************************************/
539 STATUS ERC_Deallocate_Memory(VOID *ptr)
540 {
541 ER_DEBUG_ALLOCATION *target;
542 STATUS status;
543
544 if (ptr == NULL)
545 return(NU_INVALID_POINTER);
546
547 /* Find the NU_DEBUG_ALLOCATION ptr refers to. After this call,
548 (&(target->data) == ptr) or (target == NULL). */
549 target = ERC_Memory_To_Debug(ptr);
550
551 /* Remove target from the linked list of ER_DEBUG_ALLOCATIONs */
552 status = ERC_Remove_Debug_Allocation(target);
553
554 if ((status != 0) || (target == NULL))
555 return(NU_INVALID_POINTER);
556
557 /* Maintain status variables */
558 ERD_TotalMemoryAllocated -= target->size;
559 ERD_TotalMemoryAllocations--;
560 ERD_AllocationCount--;
561
562 return(DMCE_Deallocate_Memory(target));
563 }
564
565 #endif /* NU_DEBUG_MEMORY */
566
567 /**************************************************************************
568 This routine should appear last in this file and must *NOT* use the
569 NU_ASSERT macro.
570 **************************************************************************/
571
572 #ifdef NU_ASSERT /* Don't use NU_ASSERT past this point */
573 #undef NU_ASSERT
574 #define NU_ASSERT(ignore) ((void) 0)
575 #endif
576
577 #ifdef NU_ASSERT2
578 #undef NU_ASSERT2
579 #define NU_ASSERT2(ignore) ((void) 0)
580 #endif
581
582 /*************************************************************************/
583 /* */
584 /* FUNCTION */
585 /* */
586 /* ERC_Assert */
587 /* */
588 /* DESCRIPTION */
589 /* */
590 /* This public routine is called when an assertion made by the */
591 /* NU_ASSERT (or NU_ASSERT2) macro fails. By default, this routine */
592 /* simply counts the number of failed assertions. A breakpoint can */
593 /* be set in the routine to observe failed assertions, or the */
594 /* routine can be customized to perform some action, such as */
595 /* printing the failed assertion as a message, etc. */
596 /* */
597 /* CALLED BY */
598 /* */
599 /* NU_ASSERT macro */
600 /* NU_ASSERT2 macro */
601 /* */
602 /* CALLS */
603 /* */
604 /* None */
605 /* */
606 /* INPUTS */
607 /* */
608 /* test Pointer to string of failed assertion test */
609 /* name File name of file containing failed assertion */
610 /* line Location of failed assertion in above file */
611 /* */
612 /* OUTPUTS */
613 /* */
614 /* None */
615 /* */
616 /* HISTORY */
617 /* */
618 /* NAME DATE REMARKS */
619 /* */
620 /* Todd C. Larsen 09-01-1998 Created initial revision */
621 /* */
622 /*************************************************************************/
623 #ifdef NU_DEBUG
624
625 void ERC_Assert(CHAR *test, CHAR *name, UNSIGNED line)
626 {
627 NU_SUPERV_USER_VARIABLES
628
629 #ifdef NU_ENABLE_HISTORY
630
631 /* Make an entry that corresponds to this function in the system history
632 log. */
633 HIC_Make_History_Entry(NU_ASSERT_ID, (UNSIGNED) test,
634 (UNSIGNED) name, line);
635
636 #endif
637
638 /* Switch to supervisor mode */
639 NU_SUPERVISOR_MODE();
640
641 /* Set breakpoint here to catch failed assertions. */
642 ERD_Assert_Count += 1;
643
644 /* Return to user mode */
645 NU_USER_MODE();
646 }
647
648 #endif /* NU_DEBUG */
649
650
651
652
653