📄 tclalloc.c
字号:
if (break_on_malloc && (total_mallocs >= break_on_malloc)) {
break_on_malloc = 0;
(void) fflush(stdout);
fprintf(stderr,"reached malloc break limit (%d)\n",
total_mallocs);
fprintf(stderr, "program will now enter C debugger\n");
(void) fflush(stderr);
abort();
}
current_malloc_packets++;
if (current_malloc_packets > maximum_malloc_packets)
maximum_malloc_packets = current_malloc_packets;
current_bytes_malloced += size;
if (current_bytes_malloced > maximum_bytes_malloced)
maximum_bytes_malloced = current_bytes_malloced;
if (init_malloced_bodies)
memset (result->body, 0xff, (int) size);
return result->body;
}
/*
*----------------------------------------------------------------------
*
* Tcl_DbCkfree - debugging ckfree
*
* Verify that the low and high guards are intact, and if so
* then free the buffer else panic.
*
* The guards are erased after being checked to catch duplicate
* frees.
*
* The second and third arguments are file and line, these contain
* the filename and line number corresponding to the caller.
* These are sent by the ckfree macro; it uses the preprocessor
* autodefines __FILE__ and __LINE__.
*
*----------------------------------------------------------------------
*/
int
Tcl_DbCkfree(ptr, file, line)
char * ptr;
char *file;
int line;
{
struct mem_header *memp = 0; /* Must be zero for size calc */
/*
* Since header ptr is zero, body offset will be size
*/
memp = (struct mem_header *)(((char *) ptr) - (int)memp->body);
if (alloc_tracing)
fprintf(stderr, "ckfree %lx %ld %s %d\n", memp->body,
memp->length, file, line);
if (validate_memory)
Tcl_ValidateAllMemory (file, line);
ValidateMemory (memp, file, line, TRUE);
total_frees++;
current_malloc_packets--;
current_bytes_malloced -= memp->length;
/*
* Delink from allocated list
*/
if (memp->flink != NULL)
memp->flink->blink = memp->blink;
if (memp->blink != NULL)
memp->blink->flink = memp->flink;
if (allocHead == memp)
allocHead = memp->flink;
free((char *) memp);
return 0;
}
/*
*--------------------------------------------------------------------
*
* Tcl_DbCkrealloc - debugging ckrealloc
*
* Reallocate a chunk of memory by allocating a new one of the
* right size, copying the old data to the new location, and then
* freeing the old memory space, using all the memory checking
* features of this package.
*
*--------------------------------------------------------------------
*/
char *
Tcl_DbCkrealloc(ptr, size, file, line)
char *ptr;
unsigned int size;
char *file;
int line;
{
char *new;
new = Tcl_DbCkalloc(size, file, line);
memcpy((VOID *) new, (VOID *) ptr, (int) size);
Tcl_DbCkfree(ptr, file, line);
return(new);
}
/*
*----------------------------------------------------------------------
*
* MemoryCmd --
* Implements the TCL memory command:
* memory info
* memory display
* break_on_malloc count
* trace_on_at_malloc count
* trace on|off
* validate on|off
*
* Results:
* Standard TCL results.
*
*----------------------------------------------------------------------
*/
/* ARGSUSED */
static int
MemoryCmd (clientData, interp, argc, argv)
char *clientData;
Tcl_Interp *interp;
int argc;
char **argv;
{
char *fileName;
if (argc < 2) {
Tcl_AppendResult(interp, "wrong # args: should be \"",
argv[0], " option [args..]\"", (char *) NULL);
return TCL_ERROR;
}
if (strcmp(argv[1],"trace") == 0) {
if (argc != 3)
goto bad_suboption;
alloc_tracing = (strcmp(argv[2],"on") == 0);
return TCL_OK;
}
if (strcmp(argv[1],"init") == 0) {
if (argc != 3)
goto bad_suboption;
init_malloced_bodies = (strcmp(argv[2],"on") == 0);
return TCL_OK;
}
if (strcmp(argv[1],"validate") == 0) {
if (argc != 3)
goto bad_suboption;
validate_memory = (strcmp(argv[2],"on") == 0);
return TCL_OK;
}
if (strcmp(argv[1],"trace_on_at_malloc") == 0) {
if (argc != 3)
goto argError;
if (Tcl_GetInt(interp, argv[2], &trace_on_at_malloc) != TCL_OK)
return TCL_ERROR;
return TCL_OK;
}
if (strcmp(argv[1],"break_on_malloc") == 0) {
if (argc != 3)
goto argError;
if (Tcl_GetInt(interp, argv[2], &break_on_malloc) != TCL_OK)
return TCL_ERROR;
return TCL_OK;
}
if (strcmp(argv[1],"info") == 0) {
dump_memory_info(stdout);
return TCL_OK;
}
if (strcmp(argv[1],"active") == 0) {
if (argc != 3) {
Tcl_AppendResult(interp, "wrong # args: should be \"",
argv[0], " active file", (char *) NULL);
return TCL_ERROR;
}
fileName = argv [2];
if (fileName [0] == '~')
if ((fileName = Tcl_TildeSubst (interp, fileName)) == NULL)
return TCL_ERROR;
if (Tcl_DumpActiveMemory (fileName) != TCL_OK) {
Tcl_AppendResult(interp, "error accessing ", argv[2],
(char *) NULL);
return TCL_ERROR;
}
return TCL_OK;
}
Tcl_AppendResult(interp, "bad option \"", argv[1],
"\": should be info, init, active, break_on_malloc, ",
"trace_on_at_malloc, trace, or validate", (char *) NULL);
return TCL_ERROR;
argError:
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
" ", argv[1], "count\"", (char *) NULL);
return TCL_ERROR;
bad_suboption:
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
" ", argv[1], " on|off\"", (char *) NULL);
return TCL_ERROR;
}
/*
*----------------------------------------------------------------------
*
* Tcl_InitMemory --
* Initialize the memory command.
*
*----------------------------------------------------------------------
*/
void
Tcl_InitMemory(interp)
Tcl_Interp *interp;
{
Tcl_CreateCommand (interp, "memory", MemoryCmd, (ClientData)NULL,
(void (*)())NULL);
}
#else
/*
*----------------------------------------------------------------------
*
* Tcl_Ckalloc --
* Interface to malloc when TCL_MEM_DEBUG is disabled. It does check
* that memory was actually allocated.
*
*----------------------------------------------------------------------
*/
VOID *Tcl_Ckalloc(unsigned int size) {
char *result;
result = malloc(size);
if (result == NULL) {
panic("unable to alloc %d bytes", size);
}
return result;
}
/*
*----------------------------------------------------------------------
*
* TckCkfree --
* Interface to free when TCL_MEM_DEBUG is disabled. Done here rather
* in the macro to keep some modules from being compiled with
* TCL_MEM_DEBUG enabled and some with it disabled.
*
*----------------------------------------------------------------------
*/
void Tcl_Ckfree(VOID *ptr) {
free (ptr);
}
/*
*----------------------------------------------------------------------
*
* Tcl_InitMemory --
* Dummy initialization for memory command, which is only available
* if TCL_MEM_DEBUG is on.
*
*----------------------------------------------------------------------
*/
/* ARGSUSED */
void
Tcl_InitMemory(interp)
Tcl_Interp *interp;
{
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -