The R Project SVN R

Rev

Rev 60667 | Rev 66326 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 r 1
/*
2
 *  R : A Computer Langage for Statistical Data Analysis
3
 *  Copyright (C) 1995, 1996  Robert Gentleman and Ross Ihaka
59451 ripley 4
 *  Copyright (C) 1998-2012   The R Core Team.
2 r 5
 *
6
 *  This program is free software; you can redistribute it and/or modify
7
 *  it under the terms of the GNU General Public License as published by
8
 *  the Free Software Foundation; either version 2 of the License, or
9
 *  (at your option) any later version.
10
 *
11
 *  This program is distributed in the hope that it will be useful,
12
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 *  GNU General Public License for more details.
15
 *
16
 *  You should have received a copy of the GNU General Public License
42307 ripley 17
 *  along with this program; if not, a copy is available at
18
 *  http://www.r-project.org/Licenses/
2 r 19
 */
5458 ripley 20
 
5187 hornik 21
#ifdef HAVE_CONFIG_H
7701 hornik 22
#include <config.h>
5187 hornik 23
#endif
2 r 24
 
57538 ripley 25
#define R_USE_SIGNALS 1
26
#include <Defn.h>
60667 ripley 27
#include <Internal.h>
2 r 28
 
36990 ripley 29
SEXP attribute_hidden do_debug(SEXP call, SEXP op, SEXP args, SEXP rho)
2 r 30
{
47969 rgentlem 31
    SEXP ans = R_NilValue;
32
 
1839 ihaka 33
    checkArity(op,args);
6098 pd 34
#define find_char_fun \
35
    if (isValidString(CAR(args))) {				\
36
	SEXP s;							\
63223 ripley 37
	PROTECT(s = installTrChar(STRING_ELT(CAR(args), 0)));	\
10172 luke 38
	SETCAR(args, findFun(s, rho));				\
6098 pd 39
	UNPROTECT(1);						\
1839 ihaka 40
    }
6098 pd 41
    find_char_fun
42
 
49006 rgentlem 43
    if (TYPEOF(CAR(args)) != CLOSXP && TYPEOF(CAR(args)) != SPECIALSXP 
44
         &&  TYPEOF(CAR(args)) != BUILTINSXP )
41713 ripley 45
	errorcall(call, _("argument must be a closure"));
1839 ihaka 46
    switch(PRIMVAL(op)) {
47
    case 0:
48998 rgentlem 48
	SET_RDEBUG(CAR(args), 1);
1839 ihaka 49
	break;
50
    case 1:
48998 rgentlem 51
	if( RDEBUG(CAR(args)) != 1 )
4247 rgentlem 52
	    warningcall(call, "argument is not being debugged");
48998 rgentlem 53
	SET_RDEBUG(CAR(args), 0);
1839 ihaka 54
	break;
47969 rgentlem 55
    case 2:
48998 rgentlem 56
        ans = ScalarLogical(RDEBUG(CAR(args)));
47969 rgentlem 57
        break;
48288 rgentlem 58
    case 3:
48998 rgentlem 59
        SET_RSTEP(CAR(args), 1);
48288 rgentlem 60
        break;
1839 ihaka 61
    }
47969 rgentlem 62
    return ans;
2 r 63
}
64
 
51267 ripley 65
/* primitives .primTrace and .primUntrace */
36990 ripley 66
SEXP attribute_hidden do_trace(SEXP call, SEXP op, SEXP args, SEXP rho)
2 r 67
{
1839 ihaka 68
    checkArity(op, args);
51267 ripley 69
    check1arg(args, call, "x");
6098 pd 70
 
71
    find_char_fun
72
 
1895 ihaka 73
    if (TYPEOF(CAR(args)) != CLOSXP &&
74
	TYPEOF(CAR(args)) != BUILTINSXP &&
6098 pd 75
	TYPEOF(CAR(args)) != SPECIALSXP)
40183 ripley 76
	    errorcall(call, _("argument must be a function"));
1895 ihaka 77
 
1839 ihaka 78
    switch(PRIMVAL(op)) {
79
    case 0:
48998 rgentlem 80
	SET_RTRACE(CAR(args), 1);
1839 ihaka 81
	break;
82
    case 1:
48998 rgentlem 83
	SET_RTRACE(CAR(args), 0);
1839 ihaka 84
	break;
85
    }
86
    return R_NilValue;
2 r 87
}
21102 jmc 88
 
89
 
90
/* maintain global trace state */
91
 
92
static Rboolean tracing_state = TRUE;
93
#define GET_TRACE_STATE tracing_state
94
#define SET_TRACE_STATE(value) tracing_state = value
95
 
60633 ripley 96
SEXP attribute_hidden do_traceOnOff(SEXP call, SEXP op, SEXP args, SEXP rho)
41894 ripley 97
{
60633 ripley 98
    checkArity(op, args);
99
    SEXP onOff = CAR(args);
100
 
21102 jmc 101
    Rboolean prev = GET_TRACE_STATE;
102
    if(length(onOff) > 0) {
45446 ripley 103
	Rboolean _new = asLogical(onOff);
104
	if(_new == TRUE || _new == FALSE)
105
	    SET_TRACE_STATE(_new);
106
	else
107
	    error("Value for tracingState must be TRUE or FALSE");
21102 jmc 108
    }
41894 ripley 109
    return ScalarLogical(prev);
21102 jmc 110
}
111
 
38705 ripley 112
Rboolean attribute_hidden
113
R_current_trace_state() { return GET_TRACE_STATE; }
38002 tlumley 114
 
115
 
116
/* memory tracing */
117
/* report when a traced object is duplicated */
118
 
51256 ripley 119
SEXP attribute_hidden do_tracemem(SEXP call, SEXP op, SEXP args, SEXP rho)
38002 tlumley 120
{
121
#ifdef R_MEMORY_PROFILING
122
    SEXP object;
123
    char buffer[20];
124
 
125
    checkArity(op, args);
51267 ripley 126
    check1arg(args, call, "x");
38002 tlumley 127
 
38426 ripley 128
    object = CAR(args);
40183 ripley 129
    if (TYPEOF(object) == CLOSXP ||
38002 tlumley 130
	TYPEOF(object) == BUILTINSXP ||
131
	TYPEOF(object) == SPECIALSXP)
40183 ripley 132
	errorcall(call, _("argument must not be a function"));
38002 tlumley 133
 
134
    if(object == R_NilValue)
40183 ripley 135
	errorcall(call, _("cannot trace NULL"));
38002 tlumley 136
 
137
    if(TYPEOF(object) == ENVSXP || TYPEOF(object) == PROMSXP)
40183 ripley 138
	errorcall(call,
139
		  _("'tracemem' is not useful for promise and environment objects"));
38002 tlumley 140
    if(TYPEOF(object) == EXTPTRSXP || TYPEOF(object) == WEAKREFSXP)
40183 ripley 141
	errorcall(call,
142
		  _("'tracemem' is not useful for weak reference or external pointer objects"));
38002 tlumley 143
 
48998 rgentlem 144
    SET_RTRACE(object, 1);
40185 ripley 145
    snprintf(buffer, 20, "<%p>", (void *) object);
38002 tlumley 146
    return mkString(buffer);
147
#else
40183 ripley 148
    errorcall(call, _("R was not compiled with support for memory profiling"));
38002 tlumley 149
    return R_NilValue;
150
#endif
151
}
152
 
38550 tlumley 153
 
51256 ripley 154
SEXP attribute_hidden do_untracemem(SEXP call, SEXP op, SEXP args, SEXP rho)
38002 tlumley 155
{
156
#ifdef R_MEMORY_PROFILING
157
    SEXP object;
158
 
159
    checkArity(op, args);
51267 ripley 160
    check1arg(args, call, "x");
38002 tlumley 161
 
162
    object=CAR(args);
40183 ripley 163
    if (TYPEOF(object) == CLOSXP ||
38002 tlumley 164
	TYPEOF(object) == BUILTINSXP ||
165
	TYPEOF(object) == SPECIALSXP)
40183 ripley 166
	errorcall(call, _("argument must not be a function"));
38002 tlumley 167
 
48998 rgentlem 168
    if (RTRACE(object))
169
	SET_RTRACE(object, 0);
38002 tlumley 170
#else
40183 ripley 171
    errorcall(call, _("R was not compiled with support for memory profiling"));
38002 tlumley 172
#endif
173
    return R_NilValue;
174
}
175
 
176
 
177
#ifndef R_MEMORY_PROFILING
59378 ripley 178
void memtrace_report(void* old, void *_new) {
40183 ripley 179
    return;
38002 tlumley 180
}
181
#else
40183 ripley 182
static void memtrace_stack_dump(void)
183
{
38002 tlumley 184
    RCNTXT *cptr;
38550 tlumley 185
 
38002 tlumley 186
    for (cptr = R_GlobalContext; cptr; cptr = cptr->nextcontext) {
187
	if ((cptr->callflag & (CTXT_FUNCTION | CTXT_BUILTIN))
188
	    && TYPEOF(cptr->call) == LANGSXP) {
189
	    SEXP fun = CAR(cptr->call);
190
	    Rprintf("%s ",
40705 ripley 191
		    TYPEOF(fun) == SYMSXP ? translateChar(PRINTNAME(fun)) :
38002 tlumley 192
		    "<Anonymous>");
193
	}
194
    }
195
    Rprintf("\n");
40183 ripley 196
}
38002 tlumley 197
 
59378 ripley 198
void memtrace_report(void * old, void * _new)
40183 ripley 199
{
38550 tlumley 200
    if (!R_current_trace_state()) return;
40183 ripley 201
    Rprintf("tracemem[%p -> %p]: ", (void *) old, _new);
38550 tlumley 202
    memtrace_stack_dump();
203
}
38002 tlumley 204
 
205
#endif /* R_MEMORY_PROFILING */
38550 tlumley 206
 
51256 ripley 207
SEXP attribute_hidden do_retracemem(SEXP call, SEXP op, SEXP args, SEXP rho)
38550 tlumley 208
{
209
#ifdef R_MEMORY_PROFILING
51256 ripley 210
    SEXP object, previous, ans, ap, argList;
38550 tlumley 211
    char buffer[20];
212
 
51256 ripley 213
    PROTECT(ap = list2(R_NilValue, R_NilValue));
214
    SET_TAG(ap,  install("x"));
215
    SET_TAG(CDR(ap), install("previous"));
216
    PROTECT(argList =  matchArgs(ap, args, call));
217
    if(CAR(argList) == R_MissingArg) SETCAR(argList, R_NilValue);
218
    if(CADR(argList) == R_MissingArg) SETCAR(CDR(argList), R_NilValue);
38550 tlumley 219
 
56663 ripley 220
    object = CAR(ap);
40183 ripley 221
    if (TYPEOF(object) == CLOSXP ||
38550 tlumley 222
	TYPEOF(object) == BUILTINSXP ||
223
	TYPEOF(object) == SPECIALSXP)
40183 ripley 224
	errorcall(call, _("argument must not be a function"));
38550 tlumley 225
 
56663 ripley 226
    previous = CADR(ap);
51256 ripley 227
    if(!isNull(previous) && !isString(previous))
228
	    errorcall(call, _("invalid '%s' argument"), "previous");
38550 tlumley 229
 
56663 ripley 230
    if (RTRACE(object)) {
40185 ripley 231
	snprintf(buffer, 20, "<%p>", (void *) object);
40183 ripley 232
	ans = mkString(buffer);
51256 ripley 233
    } else {
234
	R_Visible = 0;
235
	ans = R_NilValue;
236
    }
38550 tlumley 237
 
51256 ripley 238
    if (previous != R_NilValue){
48998 rgentlem 239
	SET_RTRACE(object, 1);
40183 ripley 240
	if (R_current_trace_state()) {
51256 ripley 241
	    /* FIXME: previous will have <0x....> whereas other values are
242
	       without the < > */
45446 ripley 243
	    Rprintf("tracemem[%s -> %p]: ",
51256 ripley 244
		    translateChar(STRING_ELT(previous, 0)), (void *) object);
40183 ripley 245
	    memtrace_stack_dump();
246
	}
38550 tlumley 247
    }
51256 ripley 248
    UNPROTECT(2);
38550 tlumley 249
    return ans;
250
#else
59451 ripley 251
    R_Visible = 0; /* for consistency with other case */
38550 tlumley 252
    return R_NilValue;
253
#endif
254
}