comparison gsm-fw/g23m-gsm/dl/dl_trace.c @ 673:2f7df7a314f8

gsm-fw/g23m-gsm subtree: initial import from LoCosto source
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Sun, 28 Sep 2014 23:20:04 +0000
parents
children 576c006d4b90
comparison
equal deleted inserted replaced
672:0dc6f9e8e980 673:2f7df7a314f8
1 /*
2 +-----------------------------------------------------------------------------
3 | Project :
4 | Modul :
5 +-----------------------------------------------------------------------------
6 | Copyright 2002 Texas Instruments Berlin, AG
7 | All rights reserved.
8 |
9 | This file is confidential and a trade secret of Texas
10 | Instruments Berlin, AG
11 | The receipt of or possession of this file does not convey
12 | any rights to reproduce or disclose its contents or to
13 | manufacture, use, or sell anything it may describe, in
14 | whole, or in part, without the specific written consent of
15 | Texas Instruments Berlin, AG.
16 +-----------------------------------------------------------------------------
17 | Purpose : This Modul defines the offline trace functions
18 | for the component DL of the mobile station.
19 +-----------------------------------------------------------------------------
20 */
21
22 #ifndef DL_TRACE_C
23 #define DL_TRACE_C
24
25 #define ENTITY_DL
26
27 /*==== INCLUDES ===================================================*/
28 #include "typedefs.h"
29 #include <string.h>
30 #include "vsi.h"
31 #include "pconst.cdg"
32 #include "custom.h"
33 #include "gsm.h"
34 #include "mon_dl.h"
35 #include "prim.h"
36 #include "pei.h"
37 #include "tok.h"
38 #include "ccdapi.h"
39 #include "dl.h"
40
41 /*==== EXPORT =====================================================*/
42 /*==== PRIVAT =====================================================*/
43 #if defined(DL_TRACE_ENABLED)
44 #ifdef OPTION_MULTITHREAD
45 #define TRACE_TYPE _ENTITY_PREFIXED(TRACE_TYPE)
46 #define CHANNEL _ENTITY_PREFIXED(CHANNEL)
47 #define STATES _ENTITY_PREFIXED(STATES)
48 #endif /* OPTION_MULTITHREAD */
49 LOCAL const char* const STATES[] = {
50 "INVALID",
51 "DISABLED",
52 "IDLE_DL",
53 "SUSPENDED",
54 "AWAITING_ESTABLISHMENT",
55 "MULTI_FRAME_ESTABLISHED",
56 "TIMER_RECOVERY",
57 "AWAITING_RELEASE"
58 };
59 LOCAL const char* const TRACE_TYPE[] = { "UL", "DL", "Ev", "St", "PL", "RR" };
60 LOCAL const char* const CH_TYPE[] = { " ", "SA", "SD", "FH", "FF", "CC", "BC", "PC", "PE", "CB", "BE" };
61 LOCAL const char SAPI_TYPE[] = { '0', '1', '2', '3', ' '};
62
63 LOCAL void array2hex (UBYTE *inarray, char *outarray, int size);
64
65 #if !defined(DL_IMMEDIATE_TRACE)
66
67 /*==== TEST TRACE ===================================================*/
68 #define TEST_ENTITY_DL
69
70 /*==== VARIABLES ==================================================*/
71 /*==== FUNCTIONS ==================================================*/
72 /*
73 * The Data Link Layer Trace is a cyclic buffer for
74 * debugging layer 2 problems.
75 *
76 * The buffer will be initialized at startup and will
77 * be filled by the function dl_trace() until it is full.
78 * The size of the buffer is IDLE_TRACE_SIZE.
79 *
80 * The content is
81 *
82 * trace_type (uplink, downlink, event state, alr_event, rr_event)
83 * Channel Type (SACCH, SDDCH, FACCH)
84 * real system clock
85 * State (DL states)
86 * pending disc request
87 * data (layer frame, eevnt strings, state)
88 *
89 * During IDLE mode (triggered by RX_PERIODIC_IND in ALR/TIL_main.c)
90 * an output is written to as SYST trace.
91 * (IDLE_TRACE_MAX_READED traces each trigger)
92 */
93
94 #define IDLE_TRACE_SIZE 512
95 #define IDLE_TRACE_MAX_READED 16
96
97 #if (((IDLE_TRACE_SIZE-1) & (~IDLE_TRACE_SIZE)) == (IDLE_TRACE_SIZE-1))
98 #define POWER_OF_2
99 #pragma message("IDLE_TRACE_SIZE is power of 2")
100 #else
101 #pragma message("IDLE_TRACE_SIZE is NOT power of 2")
102 #endif
103
104 typedef struct
105 {
106 UBYTE trace_type;
107 UBYTE ch_type;
108 UBYTE sapi;
109 T_TIME sysClock;
110 UBYTE disc_request;
111 UBYTE state;
112 UBYTE data [MAX_L2_FRAME_SIZE];
113 } T_IDLE_TRACE_DATA;
114
115 #ifdef OPTION_MULTITHREAD
116 #define IDLE_Trace_buffer _ENTITY_PREFIXED(IDLE_Trace_buffer)
117 #define IDLE_Trace_write_index _ENTITY_PREFIXED(IDLE_Trace_write_index)
118 #define IDLE_Trace_read_index _ENTITY_PREFIXED(IDLE_Trace_read_index)
119 #endif /* OPTION_MULTITHREAD */
120
121 GLOBAL T_IDLE_TRACE_DATA IDLE_Trace_buffer [IDLE_TRACE_SIZE];
122 GLOBAL USHORT IDLE_Trace_write_index = 0;
123 GLOBAL USHORT IDLE_Trace_read_index = 0;
124
125 LOCAL T_HANDLE sem_DL_TRC;
126
127 GLOBAL void dl_trace_init (void)
128 {
129 sem_DL_TRC = vsi_s_open (VSI_CALLER "DL_IDLE_TRACE",1);
130 if (sem_DL_TRC NEQ VSI_ERROR)
131 dl_trace_clear (0);
132 else
133 SYST_TRACE ("DL:canīt open semaphore \"DL_IDLE_TRACE\"");
134 }
135
136 GLOBAL void dl_trace_exit (void)
137 {
138 if (sem_DL_TRC NEQ VSI_ERROR)
139 vsi_s_close (VSI_CALLER sem_DL_TRC);
140 }
141
142 GLOBAL void dl_trace_clear ()
143 {
144 dl_trace_read_all (0); /* first, get all remaining traces (if exists) */
145
146 ENTER_CRITICAL_SECTION (sem_DL_TRC);
147 IDLE_Trace_write_index = IDLE_Trace_read_index = 0;
148 LEAVE_CRITICAL_SECTION (sem_DL_TRC);
149
150 TRACE_EVENT ("offline trace reset");
151 DL_OFFLINE_TRACE (TRACE_DL_EVENT, TRACE_CH_UNKNOWN, 0, "offline trace reset");
152 }
153
154 /*
155 +--------------------------------------------------------------------+
156 | PROJECT : GSM-PS (6147) MODULE : DL_COM |
157 | STATE : code ROUTINE : dl_trace |
158 +--------------------------------------------------------------------+
159
160 PURPOSE : Fill in a trace.
161
162 */
163 GLOBAL void dl_trace (UCHAR trace_type, UCHAR channel, UCHAR ch_type, UCHAR* data)
164 {
165 T_IDLE_TRACE_DATA* trace_data;
166 USHORT write_index1, write_index2;/* trace_size must not be greater than 2 */
167 UBYTE trace_size;
168
169 if (data)
170 {
171 #if defined (DISABLE_MEASREPORT_TRACE)
172 if ((ch_type EQ L2_CHANNEL_SACCH) AND
173 (data[2] EQ 0x01) AND
174 (data[3] EQ 0x03) AND
175 (data[4] EQ 0x49))
176 return;
177 #endif /* DISABLE_MEASREPORT_TRACE */
178
179 #if defined (DISABLE_EMPTY_UI)
180 if ((trace_type EQ TRACE_DOWNLINK) OR (trace_type EQ TRACE_UPLINK))
181 {
182 if ((ch_type EQ L2_CHANNEL_SACCH) AND
183 (data[3] EQ 0x03) AND
184 (data[4] EQ 0x01))
185 return;
186 else if (
187 (data[1] EQ 0x03) AND
188 (data[2] EQ 0x01))
189 return;
190 }
191 #endif /* DISABLE_EMPTY_UI */
192 }
193
194 TEST_SEMAPHORE (sem_DL_TRC);
195 ENTER_CRITICAL_SECTION(sem_DL_TRC);
196
197 trace_size = 1;
198 if ((trace_type EQ TRACE_PL_EVENT) OR (trace_type EQ TRACE_RR_EVENT))
199 {
200 if (data AND strlen ((char *)data) >= 23)
201 trace_size = 2;
202 }
203
204 #if defined(POWER_OF_2)
205 write_index1 = (IDLE_Trace_write_index + 1) & (IDLE_TRACE_SIZE - 1); /* if IDLE_TRACE_SIZE power of 2 */
206 write_index2 = (IDLE_Trace_write_index + trace_size) & (IDLE_TRACE_SIZE - 1); /* if IDLE_TRACE_SIZE power of 2 */
207 #else
208 write_index1 = (IDLE_Trace_write_index + 1) % IDLE_TRACE_SIZE; /* if IDLE_TRACE_SIZE not power of 2 */
209 write_index2 = (IDLE_Trace_write_index + trace_size) % IDLE_TRACE_SIZE; /* if IDLE_TRACE_SIZE not power of 2 */
210 #endif /* POWER_OF_2 */
211 if ((write_index1 NEQ IDLE_Trace_read_index) AND (write_index2 NEQ IDLE_Trace_read_index))
212 { /* buffer is not full */
213 trace_data = &IDLE_Trace_buffer[IDLE_Trace_write_index];
214
215 trace_data->trace_type = trace_type;
216 if ((trace_type EQ TRACE_PL_EVENT) OR (trace_type EQ TRACE_RR_EVENT))
217 {
218 trace_data->state = trace_size;
219 }
220 else
221 {
222 GET_INSTANCE_DATA;
223 trace_data->ch_type = ch_type;
224 switch (channel)
225 {
226 case C_SACCH0:
227 case C_DCCH0:
228 trace_data->disc_request = dl_data->dcch0_disc_request;
229 trace_data->state = dl_data->state [C_DCCH0];
230 trace_data->sapi = PS_SAPI_0;
231 break;
232 case C_DCCH3:
233 trace_data->disc_request = dl_data->dcch3_disc_request;
234 trace_data->state = dl_data->state [C_DCCH3];
235 trace_data->sapi = PS_SAPI_3;
236 break;
237 default:
238 trace_data->disc_request = 0;
239 trace_data->state = 0;
240 trace_data->sapi = NOT_PRESENT_8BIT;
241 break;
242 }
243 }
244
245 vsi_t_time (VSI_CALLER &trace_data->sysClock);
246
247 if (data)
248 {
249 memcpy (trace_data->data, data, MAX_L2_FRAME_SIZE);
250 if ((trace_type NEQ TRACE_UPLINK) AND (trace_type NEQ TRACE_DOWNLINK))
251 {
252 trace_data->data[MAX_L2_FRAME_SIZE-1] = 0;
253 }
254
255 if (trace_size EQ 2)
256 {
257 if (IDLE_Trace_write_index EQ (IDLE_TRACE_SIZE - 1))/* the last buffer index ? */
258 trace_data = &IDLE_Trace_buffer[0];/* -> overflow to the first buffer index */
259 else
260 trace_data++;
261 memcpy (trace_data->data, data+MAX_L2_FRAME_SIZE-1, MAX_L2_FRAME_SIZE-1);
262 trace_data->data[MAX_L2_FRAME_SIZE-1] = 0;
263 }
264 }
265
266 IDLE_Trace_write_index = write_index2;
267 }/* endif buffer is not full */
268
269 LEAVE_CRITICAL_SECTION (sem_DL_TRC);
270
271 #if defined(_SIMULATION_)
272 dl_trace_read (0);
273 #endif /* _SIMULATION_ */
274 }
275
276 /*
277 +--------------------------------------------------------------------+
278 | PROJECT : GSM-PS (6147) MODULE : DL_COM |
279 | STATE : code ROUTINE : dl_trace_read |
280 +--------------------------------------------------------------------+
281
282 PURPOSE : Fill in a trace.
283
284 */
285 GLOBAL void dl_trace_read_all ()
286 {
287 USHORT write_index, read_index;
288
289 do
290 {
291 dl_trace_read ();
292
293 ENTER_CRITICAL_SECTION (sem_DL_TRC);
294 write_index = IDLE_Trace_write_index;
295 read_index = IDLE_Trace_read_index;
296 LEAVE_CRITICAL_SECTION (sem_DL_TRC);
297 } while (read_index NEQ write_index);
298 }
299
300 GLOBAL void dl_trace_read ()
301 {
302 T_IDLE_TRACE_DATA* trace_data;
303 USHORT write_index, read_index, left;
304 UBYTE trace_size;
305 static char buffer[80];
306 UBYTE j, o, readed = 0;
307
308 TEST_SEMAPHORE (sem_DL_TRC);
309
310 ENTER_CRITICAL_SECTION (sem_DL_TRC);
311 write_index = IDLE_Trace_write_index;
312 read_index = IDLE_Trace_read_index;
313 LEAVE_CRITICAL_SECTION (sem_DL_TRC);
314
315 if (read_index EQ write_index)
316 {
317 #if defined (_TARGET_) AND !defined( GPRS ) AND defined(FF_GTI)
318 sleep_mode ();
319 #endif /* _TARGET_ AND !GPRS AND !FF_GTI */
320 return;
321 }
322
323 while (read_index NEQ write_index)
324 {
325 ENTER_CRITICAL_SECTION (sem_DL_TRC);
326 trace_data = &IDLE_Trace_buffer[read_index];
327 LEAVE_CRITICAL_SECTION (sem_DL_TRC);
328
329 #if defined(POWER_OF_2)
330 left = (write_index - read_index - 1) & (IDLE_TRACE_SIZE-1);
331 #else
332 left = (IDLE_TRACE_SIZE + write_index - read_index - 1) % IDLE_TRACE_SIZE;
333 #endif /* POWER_OF_2 */
334
335 if (trace_data->ch_type > ELEMENTS(CH_TYPE))
336 trace_data->ch_type = 0;
337
338 if (trace_data->sapi >= ELEMENTS (SAPI_TYPE))
339 trace_data->sapi = ELEMENTS (SAPI_TYPE) - 1;
340
341 trace_size = 1;/* default */
342 switch (trace_data->trace_type)
343 {
344 case TRACE_UPLINK:
345 case TRACE_DOWNLINK:
346 sprintf (buffer, "[%03d]:%07lu %c%d %s %s ",
347 left,
348 trace_data->sysClock,
349 trace_data->disc_request?'D':' ',
350 trace_data->state,
351 TRACE_TYPE[trace_data->trace_type],
352 CH_TYPE[trace_data->ch_type]);
353 o = strlen (buffer);
354 array2hex (trace_data->data, buffer+o, 23);
355 break;
356
357 case TRACE_DL_EVENT:
358 sprintf (buffer, "[%03d]:%07lu %c%d Ev %s%c %s",
359 left,
360 trace_data->sysClock,
361 trace_data->disc_request?'D':' ',
362 trace_data->state,
363 CH_TYPE[trace_data->ch_type],
364 SAPI_TYPE[trace_data->sapi],
365 trace_data->data);
366 break;
367
368 case TRACE_PL_EVENT:
369 case TRACE_RR_EVENT:
370 trace_size = trace_data->state;
371 if (trace_size EQ 2)
372 {
373 T_IDLE_TRACE_DATA *trace_data2;
374 if (read_index EQ (IDLE_TRACE_SIZE - 1))/* the last buffer index ? */
375 trace_data2 = &IDLE_Trace_buffer[0];/* -> overflow to the first buffer index */
376 else
377 trace_data2 = trace_data+1;
378
379 sprintf (buffer, "[%03d]:%07lu %d Ev %s %s%s",
380 left,
381 trace_data->sysClock,
382 trace_data->state,
383 TRACE_TYPE[trace_data->trace_type],
384 trace_data->data,
385 trace_data2->data);
386 }
387 else
388 {
389 sprintf (buffer, "[%03d]:%07lu %d Ev %s %s",
390 left,
391 trace_data->sysClock,
392 trace_data->state,
393 TRACE_TYPE[trace_data->trace_type],
394 trace_data->data);
395 }
396 break;
397
398 case TRACE_CHSTATE:
399 sprintf (buffer, "[%03d]:%07lu %c%d ST %s%c state=%s",
400 left,
401 trace_data->sysClock,
402 trace_data->disc_request?'D':' ',
403 trace_data->state,
404 CH_TYPE[trace_data->ch_type],
405 SAPI_TYPE[trace_data->sapi],
406 STATES[trace_data->state]);
407 break;
408
409 default:
410 buffer[0] = 0;
411 break;
412 }
413
414 if (buffer[0])
415 {
416 SYST_TRACE (buffer);
417 }
418 else
419 {
420 SYST_TRACE ("dl_trace_read() failed");
421 }
422
423 ENTER_CRITICAL_SECTION (sem_DL_TRC);
424 trace_data->sysClock = 0; /* readed */
425 IDLE_Trace_read_index += trace_size;
426 #if defined(POWER_OF_2)
427 IDLE_Trace_read_index &= (IDLE_TRACE_SIZE-1);/* if power of 2 */
428 #else
429 IDLE_Trace_read_index %= IDLE_TRACE_SIZE; /* if not power of 2 */
430 #endif /* POWER_OF_2 */
431 read_index = IDLE_Trace_read_index;
432 write_index = IDLE_Trace_write_index;
433 LEAVE_CRITICAL_SECTION (sem_DL_TRC);
434
435 if (readed++ >= IDLE_TRACE_MAX_READED)
436 break;
437 }/* endwhile */
438 }
439
440 #else /* DL_IMMEDIATE_TRACE */
441
442 #define IMM_TRACE_SIZE 2
443 typedef struct
444 {
445 UBYTE sapi;
446 T_TIME sysClock;
447 UBYTE disc_request;
448 UBYTE state;
449 UBYTE data [IMM_TRACE_SIZE*MAX_L2_FRAME_SIZE];
450 } T_TRACE_DATA;
451
452 #ifdef OPTION_MULTITHREAD
453 #define print_buffer _ENTITY_PREFIXED(print_buffer)
454 #define trace_buffer _ENTITY_PREFIXED(trace_buffer)
455 #endif /* OPTION_MULTITHREAD */
456 LOCAL char print_buffer[25+IMM_TRACE_SIZE*MAX_L2_FRAME_SIZE];
457 LOCAL T_TRACE_DATA trace_buffer;
458
459 /*
460 +--------------------------------------------------------------------+
461 | PROJECT : GSM-PS (6147) MODULE : DL_COM |
462 | STATE : code ROUTINE : dl_trace |
463 +--------------------------------------------------------------------+
464
465 PURPOSE : Fill in a trace.
466
467 */
468
469 GLOBAL void dl_fast_trace (UBYTE trace_type, UBYTE channel, UBYTE ch_type,
470 T_TIME trace_time, ULONG trace_mask, UBYTE* data)
471 {
472 T_TRACE_DATA* trace_data;
473 UBYTE o;
474
475 /* While TC_USER2 is set, measurements and empty frames will be traced always */
476 if (data AND ((trace_mask & TC_USER2) EQ 0))
477 {
478 if ((ch_type EQ L2_CHANNEL_SACCH) AND
479 (data[2] EQ 0x01) AND
480 (data[3] EQ 0x03) AND
481 (data[4] EQ 0x49))
482 return;
483
484 if ((trace_type EQ TRACE_DOWNLINK) OR (trace_type EQ TRACE_UPLINK))
485 {
486 if ((ch_type EQ L2_CHANNEL_SACCH) AND
487 (data[3] EQ 0x03) AND
488 (data[4] EQ 0x01))
489 return;
490 else if (
491 (data[1] EQ 0x03) AND
492 (data[2] EQ 0x01))
493 return;
494 }
495 }
496
497 trace_data = &trace_buffer;
498 trace_data->sysClock = trace_time;
499 if (!((trace_type EQ TRACE_PL_EVENT) OR (trace_type EQ TRACE_RR_EVENT)))
500 {
501 GET_INSTANCE_DATA;
502 switch (channel)
503 {
504 case C_SACCH0:
505 case C_DCCH0:
506 trace_data->disc_request = dl_data->dcch0_disc_request;
507 trace_data->state = dl_data->state [C_DCCH0];
508 trace_data->sapi = PS_SAPI_0;
509 break;
510 case C_DCCH3:
511 trace_data->disc_request = dl_data->dcch3_disc_request;
512 trace_data->state = dl_data->state [C_DCCH3];
513 trace_data->sapi = PS_SAPI_3;
514 break;
515 default:
516 trace_data->disc_request = 0;
517 trace_data->state = 0;
518 trace_data->sapi = NOT_PRESENT_8BIT;
519 break;
520 }
521 }
522
523 if (data)
524 {
525 if ((trace_type EQ TRACE_UPLINK) OR (trace_type EQ TRACE_DOWNLINK))
526 {
527 memcpy (trace_data->data, data, MAX_L2_FRAME_SIZE);
528 }
529 else
530 {
531 strncpy ((char *)trace_data->data, (char *)data, IMM_TRACE_SIZE*MAX_L2_FRAME_SIZE-1);
532 trace_data->data[IMM_TRACE_SIZE*MAX_L2_FRAME_SIZE-1] = 0;
533 }
534 }
535 else
536 {
537 trace_data->data[0] = 0;
538 }
539
540
541 if (ch_type > ELEMENTS(CH_TYPE))
542 ch_type = 0;
543
544 if (trace_data->sapi >= ELEMENTS (SAPI_TYPE))
545 trace_data->sapi = ELEMENTS (SAPI_TYPE) - 1;
546
547 switch (trace_type)
548 {
549 case TRACE_UPLINK:
550 case TRACE_DOWNLINK:
551 sprintf (print_buffer, "DLTRC:%07lu %c%d %s %s%c ",
552 trace_data->sysClock,
553 trace_data->disc_request?'D':' ',
554 trace_data->state,
555 TRACE_TYPE[trace_type],
556 CH_TYPE[ch_type],
557 SAPI_TYPE[trace_data->sapi]);
558 o = strlen (print_buffer);
559 array2hex (trace_data->data, print_buffer+o, 23);
560 break;
561
562 case TRACE_DL_EVENT:
563 sprintf (print_buffer, "DLTRC:%07lu %c%d Ev %s%c %s",
564 trace_data->sysClock,
565 trace_data->disc_request?'D':' ',
566 trace_data->state,
567 CH_TYPE[ch_type],
568 SAPI_TYPE[trace_data->sapi],
569 trace_data->data);
570 break;
571
572 case TRACE_PL_EVENT:
573 case TRACE_RR_EVENT:
574 sprintf (print_buffer, "DLTRC:%07lu %d Ev %s %s",
575 trace_data->sysClock,
576 trace_data->state,
577 TRACE_TYPE[trace_type],
578 trace_data->data);
579 break;
580
581 case TRACE_CHSTATE:
582 sprintf (print_buffer, "DLTRC:%07lu %c%d ST %s%c state=%s",
583 trace_data->sysClock,
584 trace_data->disc_request?'D':' ',
585 trace_data->state,
586 CH_TYPE[ch_type],
587 SAPI_TYPE[trace_data->sapi],
588 STATES[trace_data->state]);
589 break;
590
591 default:
592 print_buffer[0] = 0;
593 break;
594 }
595
596 TRACE_USER_CLASS (TC_USER1, print_buffer);
597
598 #if 0
599 if (print_buffer[0])
600 {
601 #if defined(_SIMULATION_)
602 TRACE_EVENT_WIN (print_buffer);
603 #else /* _SIMULATION_ */
604 SYST_TRACE_P ((DLTRC,print_buffer));
605 #endif /* _SIMULATION_ */
606 }
607 #endif /* 0 */
608 }
609 #endif /* DL_IMMEDIATE_TRACE */
610
611 LOCAL void array2hex (UBYTE *inarray, char *outarray, int size)
612 {
613 int col=0, n=0;
614 UBYTE b, nh, nl;
615
616 while (n < size)
617 {
618 b = inarray[n++];
619 nh = b>>4;
620 nl = b&0x0f;
621 outarray[col++] = nh > 9 ? nh + 'A' - 10 : nh + '0';
622 outarray[col++] = nl > 9 ? nl + 'A' - 10 : nl + '0';
623 }
624 outarray[col] = 0;
625 }
626 #endif /* DL_TRACE_ENABLED */
627
628 #if defined (DL_TRACE_PFREE)
629 GLOBAL void* my_pfree(void *pointer, int line, char *file)
630 {
631
632 char buffer[23];
633 sprintf (buffer, "%s#%u:%p", file+2, line, pointer);
634 dl_trace (TRACE_DL_EVENT, TRACE_CH_UNKNOWN, buffer);
635
636 if (pointer)
637 {
638 PFREE (pointer);
639 }
640 else
641 {
642 SYST_TRACE_P((SYST, "%s#%u: PFREE(NULL)", file, line));
643 }
644
645 return NULL;
646 }
647 #endif /* DL_TRACE_PFREE */
648
649 #endif /* DL_TRACE_C */
650