summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Nieder <jrnieder@gmail.com>2014-12-02 21:26:03 -0800
committerJunio C Hamano <gitster@pobox.com>2014-12-03 14:43:24 -0800
commitb6a2868506ff04a6cd6db4142db9fe23177d5b0a (patch)
tree3034309d997b711ef1629ffff6ab44fc3fe6942f
parent8ec1e0197634b4a2bff76e19c6a0ba5624d6f3b7 (diff)
downloadgit-b6a2868506ff04a6cd6db4142db9fe23177d5b0a.tar.gz
hold_lock_file_for_update: pass error message back through a strbuf
This makes it more obvious when callers forget to print a message on error, while still giving callers a chance to clean up before exiting. Signed-off-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--Documentation/technical/api-lockfile.txt33
-rw-r--r--builtin/apply.c5
-rw-r--r--builtin/commit.c9
-rw-r--r--builtin/gc.c8
-rw-r--r--bundle.c10
-rw-r--r--config.c18
-rw-r--r--credential-store.c8
-rw-r--r--fast-import.c8
-rw-r--r--lockfile.c26
-rw-r--r--lockfile.h8
-rw-r--r--read-cache.c9
-rw-r--r--refs.c17
-rw-r--r--rerere.c7
-rw-r--r--sequencer.c19
-rw-r--r--shallow.c16
15 files changed, 101 insertions, 100 deletions
diff --git a/Documentation/technical/api-lockfile.txt b/Documentation/technical/api-lockfile.txt
index fa60cfddc8..8cb670419f 100644
--- a/Documentation/technical/api-lockfile.txt
+++ b/Documentation/technical/api-lockfile.txt
@@ -87,21 +87,8 @@ Error handling
--------------
The `hold_lock_file_*` functions return a file descriptor on success
-or -1 on failure (unless `LOCK_DIE_ON_ERROR` is used; see below). On
-errors, `errno` describes the reason for failure. Errors can be
-reported by passing `errno` to one of the following helper functions:
-
-unable_to_lock_message::
-
- Append an appropriate error message to a `strbuf`.
-
-unable_to_lock_error::
-
- Emit an appropriate error message using `error()`.
-
-unable_to_lock_die::
-
- Emit an appropriate error message and `die()`.
+or -1 on failure. On errors, a message describing the reason for
+failure is appended to the strbuf specified using the 'err' argument.
Similarly, `commit_lock_file`, `commit_lock_file_to`, and
`close_lock_file` return 0 on success. On failure they set `errno`
@@ -111,7 +98,7 @@ appropriately, do their best to roll back the lockfile, and return -1.
Flags
-----
-The following flags can be passed to `hold_lock_file_for_update` or
+The following flag can be passed to `hold_lock_file_for_update` or
`hold_lock_file_for_append`:
LOCK_NO_DEREF::
@@ -136,22 +123,16 @@ LOCK_OUTSIDE_REPOSITORY:
For example, this flag should be set when locking a configuration
file in the user's home directory.
-LOCK_DIE_ON_ERROR::
-
- If a lock is already taken for the file, `die()` with an error
- message. If this option is not specified, trying to lock a
- file that is already locked returns -1 to the caller.
-
-
The functions
-------------
hold_lock_file_for_update::
Take a pointer to `struct lock_file`, the path of the file to
- be locked (e.g. `$GIT_DIR/index`) and a flags argument (see
- above). Attempt to create a lockfile for the destination and
- return the file descriptor for writing to the file.
+ be locked (e.g. `$GIT_DIR/index`), a flags argument (see
+ above), and a strbuf for error messages. Attempt to create a
+ lockfile for the destination and return the file descriptor for
+ writing to the file.
hold_lock_file_for_append::
diff --git a/builtin/apply.c b/builtin/apply.c
index cda438f6e9..07626fb8c0 100644
--- a/builtin/apply.c
+++ b/builtin/apply.c
@@ -3711,6 +3711,7 @@ static void build_fake_ancestor(struct patch *list, const char *filename)
struct patch *patch;
struct index_state result = { NULL };
static struct lock_file lock;
+ struct strbuf err = STRBUF_INIT;
/* Once we start supporting the reverse patch, it may be
* worth showing the new sha1 prefix, but until then...
@@ -3748,11 +3749,13 @@ static void build_fake_ancestor(struct patch *list, const char *filename)
die ("Could not add %s to temporary index", name);
}
- hold_lock_file_for_update(&lock, filename, LOCK_DIE_ON_ERROR);
+ if (hold_lock_file_for_update(&lock, filename, 0, &err) < 0)
+ die("%s", err.buf);
if (write_locked_index(&result, &lock, COMMIT_LOCK))
die ("Could not write temporary index to %s", filename);
discard_index(&result);
+ strbuf_release(&err);
}
static void stat_patch_list(struct patch *patch)
diff --git a/builtin/commit.c b/builtin/commit.c
index edc44939ba..f64024c685 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -468,10 +468,11 @@ static const char *prepare_index(int argc, const char **argv, const char *prefix
if (write_locked_index(&the_index, &index_lock, CLOSE_LOCK))
die(_("unable to write new_index file"));
- hold_lock_file_for_update(&false_lock,
- git_path("next-index-%"PRIuMAX,
- (uintmax_t) getpid()),
- LOCK_DIE_ON_ERROR);
+ if (hold_lock_file_for_update(&false_lock,
+ git_path("next-index-%"PRIuMAX,
+ (uintmax_t) getpid()), 0,
+ &err) < 0)
+ die("%s", err.buf);
create_base_index(current_head);
add_remove_files(&partial);
diff --git a/builtin/gc.c b/builtin/gc.c
index 005adbebea..86e9eca4be 100644
--- a/builtin/gc.c
+++ b/builtin/gc.c
@@ -190,6 +190,7 @@ static const char *lock_repo_for_gc(int force, pid_t* ret_pid)
static struct lock_file lock;
char my_host[128];
struct strbuf sb = STRBUF_INIT;
+ struct strbuf err = STRBUF_INIT;
struct stat st;
uintmax_t pid;
FILE *fp;
@@ -202,8 +203,9 @@ static const char *lock_repo_for_gc(int force, pid_t* ret_pid)
if (gethostname(my_host, sizeof(my_host)))
strcpy(my_host, "unknown");
- fd = hold_lock_file_for_update(&lock, git_path("gc.pid"),
- LOCK_DIE_ON_ERROR);
+ fd = hold_lock_file_for_update(&lock, git_path("gc.pid"), 0, &err);
+ if (fd < 0)
+ die("%s", err.buf);
if (!force) {
static char locking_host[128];
int should_exit;
@@ -231,6 +233,7 @@ static const char *lock_repo_for_gc(int force, pid_t* ret_pid)
if (fd >= 0)
rollback_lock_file(&lock);
*ret_pid = pid;
+ strbuf_release(&err);
return locking_host;
}
}
@@ -245,6 +248,7 @@ static const char *lock_repo_for_gc(int force, pid_t* ret_pid)
sigchain_push_common(remove_pidfile_on_signal);
atexit(remove_pidfile);
+ strbuf_release(&err);
return NULL;
}
diff --git a/bundle.c b/bundle.c
index 2e2dbd50ef..db03782062 100644
--- a/bundle.c
+++ b/bundle.c
@@ -417,9 +417,13 @@ int create_bundle(struct bundle_header *header, const char *path,
bundle_to_stdout = !strcmp(path, "-");
if (bundle_to_stdout)
bundle_fd = 1;
- else
- bundle_fd = hold_lock_file_for_update(&lock, path,
- LOCK_DIE_ON_ERROR);
+ else {
+ struct strbuf err = STRBUF_INIT;
+ bundle_fd = hold_lock_file_for_update(&lock, path, 0, &err);
+ if (bundle_fd < 0)
+ die("%s", err.buf);
+ strbuf_release(&err);
+ }
/* write signature */
write_or_die(bundle_fd, bundle_signature, strlen(bundle_signature));
diff --git a/config.c b/config.c
index dacde5fb6f..4117ff0724 100644
--- a/config.c
+++ b/config.c
@@ -1923,6 +1923,7 @@ int git_config_set_multivar_in_file(const char *config_filename,
int fd = -1, in_fd;
int ret;
struct lock_file *lock = NULL;
+ struct strbuf err = STRBUF_INIT;
char *filename_buf = NULL;
/* parse-key returns negative; flip the sign to feed exit(3) */
@@ -1941,14 +1942,9 @@ int git_config_set_multivar_in_file(const char *config_filename,
*/
lock = xcalloc(1, sizeof(struct lock_file));
fd = hold_lock_file_for_update(lock, config_filename,
- LOCK_OUTSIDE_REPOSITORY);
+ LOCK_OUTSIDE_REPOSITORY, &err);
if (fd < 0) {
- struct strbuf err = STRBUF_INIT;
-
- unable_to_lock_message(config_filename,
- LOCK_OUTSIDE_REPOSITORY, errno, &err);
error("%s", err.buf);
- strbuf_release(&err);
free(store.key);
ret = CONFIG_NO_LOCK;
goto out_free;
@@ -2126,6 +2122,7 @@ out_free:
if (lock)
rollback_lock_file(lock);
free(filename_buf);
+ strbuf_release(&err);
return ret;
write_err_out:
@@ -2203,6 +2200,7 @@ int git_config_rename_section_in_file(const char *config_filename,
int ret = 0, remove = 0;
char *filename_buf = NULL;
struct lock_file *lock;
+ struct strbuf err = STRBUF_INIT;
int out_fd;
char buf[1024];
FILE *config_file;
@@ -2218,14 +2216,9 @@ int git_config_rename_section_in_file(const char *config_filename,
lock = xcalloc(1, sizeof(struct lock_file));
out_fd = hold_lock_file_for_update(lock, config_filename,
- LOCK_OUTSIDE_REPOSITORY);
+ LOCK_OUTSIDE_REPOSITORY, &err);
if (out_fd < 0) {
- struct strbuf err = STRBUF_INIT;
-
- unable_to_lock_message(config_filename,
- LOCK_OUTSIDE_REPOSITORY, errno, &err);
ret = error("%s", err.buf);
- strbuf_release(&err);
goto out;
}
@@ -2295,6 +2288,7 @@ unlock_and_out:
ret = error("could not commit config file %s", config_filename);
out:
free(filename_buf);
+ strbuf_release(&err);
return ret;
}
diff --git a/credential-store.c b/credential-store.c
index cd71156d80..beffa87e55 100644
--- a/credential-store.c
+++ b/credential-store.c
@@ -55,13 +55,17 @@ static void print_line(struct strbuf *buf)
static void rewrite_credential_file(const char *fn, struct credential *c,
struct strbuf *extra)
{
- hold_lock_file_for_update(&credential_lock, fn,
- LOCK_DIE_ON_ERROR | LOCK_OUTSIDE_REPOSITORY);
+ struct strbuf err = STRBUF_INIT;
+
+ if (hold_lock_file_for_update(&credential_lock, fn,
+ LOCK_OUTSIDE_REPOSITORY, &err) < 0);
+ die("%s", err.buf);
if (extra)
print_line(extra);
parse_credential_file(fn, c, NULL, print_line);
if (commit_lock_file(&credential_lock) < 0)
die_errno("unable to commit credential store");
+ strbuf_release(&err);
}
static void store_credential(const char *fn, struct credential *c)
diff --git a/fast-import.c b/fast-import.c
index bf8faa9d9f..736c37b2e5 100644
--- a/fast-import.c
+++ b/fast-import.c
@@ -1794,21 +1794,19 @@ static void dump_marks_helper(FILE *f,
static void dump_marks(void)
{
static struct lock_file mark_lock;
+ struct strbuf err = STRBUF_INIT;
FILE *f;
if (!export_marks_file)
return;
if (hold_lock_file_for_update(&mark_lock, export_marks_file,
- LOCK_OUTSIDE_REPOSITORY) < 0) {
- struct strbuf err = STRBUF_INIT;
-
- unable_to_lock_message(export_marks_file,
- LOCK_OUTSIDE_REPOSITORY, errno, &err);
+ LOCK_OUTSIDE_REPOSITORY, &err) < 0) {
failure |= error("%s", err.buf);
strbuf_release(&err);
return;
}
+ strbuf_release(&err);
f = fdopen_lock_file(&mark_lock, "w");
if (!f) {
diff --git a/lockfile.c b/lockfile.c
index 102584f0fe..a79679bdc5 100644
--- a/lockfile.c
+++ b/lockfile.c
@@ -98,8 +98,8 @@ static void resolve_symlink(struct strbuf *path)
strbuf_reset(&link);
}
-/* Make sure errno contains a meaningful value on error */
-static int lock_file(struct lock_file *lk, const char *path, int flags)
+static int lock_file(struct lock_file *lk, const char *path,
+ int flags, struct strbuf *err)
{
size_t pathlen = strlen(path);
@@ -134,16 +134,16 @@ static int lock_file(struct lock_file *lk, const char *path, int flags)
strbuf_addstr(&lk->filename, LOCK_SUFFIX);
lk->fd = open(lk->filename.buf, O_RDWR | O_CREAT | O_EXCL, 0666);
if (lk->fd < 0) {
+ unable_to_lock_message(path, flags, errno, err);
strbuf_reset(&lk->filename);
return -1;
}
lk->owner = getpid();
lk->active = 1;
if (adjust_shared_perm(lk->filename.buf)) {
- int save_errno = errno;
- error("cannot fix permission bits on %s", lk->filename.buf);
+ strbuf_addf(err, "cannot fix permission bits on %s",
+ lk->filename.buf);
rollback_lock_file(lk);
- errno = save_errno;
return -1;
}
return lk->fd;
@@ -178,13 +178,10 @@ NORETURN void unable_to_lock_die(const char *path, int flags, int err)
die("%s", buf.buf);
}
-/* This should return a meaningful errno on failure */
-int hold_lock_file_for_update(struct lock_file *lk, const char *path, int flags)
+int hold_lock_file_for_update(struct lock_file *lk, const char *path,
+ int flags, struct strbuf *err)
{
- int fd = lock_file(lk, path, flags);
- if (fd < 0 && (flags & LOCK_DIE_ON_ERROR))
- unable_to_lock_die(path, flags, errno);
- return fd;
+ return lock_file(lk, path, flags, err);
}
int hold_lock_file_for_append(struct lock_file *lk, const char *path,
@@ -192,14 +189,11 @@ int hold_lock_file_for_append(struct lock_file *lk, const char *path,
{
int fd, orig_fd;
- assert(!(flags & LOCK_DIE_ON_ERROR));
assert(err && !err->len);
- fd = lock_file(lk, path, flags);
- if (fd < 0) {
- unable_to_lock_message(path, flags, errno, err);
+ fd = lock_file(lk, path, flags, err);
+ if (fd < 0)
return fd;
- }
orig_fd = open(path, O_RDONLY);
if (orig_fd < 0) {
diff --git a/lockfile.h b/lockfile.h
index 779a992e28..6d0a9bbe5b 100644
--- a/lockfile.h
+++ b/lockfile.h
@@ -68,14 +68,14 @@ struct lock_file {
#define LOCK_SUFFIX ".lock"
#define LOCK_SUFFIX_LEN 5
-#define LOCK_DIE_ON_ERROR 1
-#define LOCK_NO_DEREF 2
-#define LOCK_OUTSIDE_REPOSITORY 4
+#define LOCK_NO_DEREF 1
+#define LOCK_OUTSIDE_REPOSITORY 2
extern void unable_to_lock_message(const char *path, int, int err,
struct strbuf *buf);
extern NORETURN void unable_to_lock_die(const char *path, int, int err);
-extern int hold_lock_file_for_update(struct lock_file *, const char *path, int);
+extern int hold_lock_file_for_update(struct lock_file *, const char *path,
+ int, struct strbuf *err);
extern int hold_lock_file_for_append(struct lock_file *, const char *path,
int, struct strbuf *err);
extern FILE *fdopen_lock_file(struct lock_file *, const char *mode);
diff --git a/read-cache.c b/read-cache.c
index 2ce1a763ac..229eea02f2 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -1370,14 +1370,7 @@ static int read_index_extension(struct index_state *istate,
int hold_locked_index(struct lock_file *lk, struct strbuf *err)
{
- const char *path;
- int fd;
-
- path = get_index_file();
- fd = hold_lock_file_for_update(lk, path, 0);
- if (fd < 0)
- unable_to_lock_message(path, 0, errno, err);
- return fd;
+ return hold_lock_file_for_update(lk, get_index_file(), 0, err);
}
int read_index(struct index_state *istate)
diff --git a/refs.c b/refs.c
index 39e43cf339..f39c29c580 100644
--- a/refs.c
+++ b/refs.c
@@ -2229,6 +2229,7 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname,
const struct string_list *skip,
int flags, int *type_p)
{
+ struct strbuf err = STRBUF_INIT;
char *ref_file;
const char *orig_refname = refname;
struct ref_lock *lock;
@@ -2316,22 +2317,25 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname,
goto error_return;
}
- lock->lock_fd = hold_lock_file_for_update(lock->lk, ref_file, lflags);
+ lock->lock_fd = hold_lock_file_for_update(lock->lk, ref_file, lflags, &err);
if (lock->lock_fd < 0) {
- if (errno == ENOENT && --attempts_remaining > 0)
+ if (errno == ENOENT && --attempts_remaining > 0) {
/*
* Maybe somebody just deleted one of the
* directories leading to ref_file. Try
* again:
*/
+ strbuf_reset(&err);
goto retry;
- else
- unable_to_lock_die(ref_file, lflags, errno);
+ }
+ die("%s", err.buf);
}
+ strbuf_release(&err);
return old_sha1 ? verify_lock(lock, old_sha1, mustexist) : lock;
error_return:
unlock_ref(lock);
+ strbuf_release(&err);
errno = last_errno;
return NULL;
}
@@ -2375,10 +2379,9 @@ int lock_packed_refs(struct strbuf *err)
{
struct packed_ref_cache *packed_ref_cache;
- if (hold_lock_file_for_update(&packlock, git_path("packed-refs"), 0) < 0) {
- unable_to_lock_message(git_path("packed-refs"), 0, errno, err);
+ if (hold_lock_file_for_update(&packlock,
+ git_path("packed-refs"), 0, err) < 0)
return -1;
- }
/*
* Get the current packed-refs while holding the lock. If the
diff --git a/rerere.c b/rerere.c
index 93de999f89..26573dba41 100644
--- a/rerere.c
+++ b/rerere.c
@@ -600,6 +600,7 @@ static int is_rerere_enabled(void)
int setup_rerere(struct string_list *merge_rr, int flags)
{
+ struct strbuf err = STRBUF_INIT;
int fd;
git_rerere_config();
@@ -609,9 +610,11 @@ int setup_rerere(struct string_list *merge_rr, int flags)
if (flags & (RERERE_AUTOUPDATE|RERERE_NOAUTOUPDATE))
rerere_autoupdate = !!(flags & RERERE_AUTOUPDATE);
merge_rr_path = git_pathdup("MERGE_RR");
- fd = hold_lock_file_for_update(&write_lock, merge_rr_path,
- LOCK_DIE_ON_ERROR);
+ fd = hold_lock_file_for_update(&write_lock, merge_rr_path, 0, &err);
+ if (fd < 0)
+ die("%s", err.buf);
read_rr(merge_rr);
+ strbuf_release(&err);
return fd;
}
diff --git a/sequencer.c b/sequencer.c
index 3b3a869c3b..c0d8864e15 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -204,14 +204,17 @@ static void print_advice(int show_hint, struct replay_opts *opts)
static void write_message(struct strbuf *msgbuf, const char *filename)
{
static struct lock_file msg_file;
+ struct strbuf err = STRBUF_INIT;
- int msg_fd = hold_lock_file_for_update(&msg_file, filename,
- LOCK_DIE_ON_ERROR);
+ int msg_fd = hold_lock_file_for_update(&msg_file, filename, 0, &err);
+ if (msg_fd < 0)
+ die("%s", err.buf);
if (write_in_full(msg_fd, msgbuf->buf, msgbuf->len) < 0)
die_errno(_("Could not write to %s"), filename);
strbuf_release(msgbuf);
if (commit_lock_file(&msg_file) < 0)
die(_("Error wrapping up %s"), filename);
+ strbuf_release(&err);
}
static struct tree *empty_tree(void)
@@ -854,14 +857,18 @@ static void save_head(const char *head)
const char *head_file = git_path(SEQ_HEAD_FILE);
static struct lock_file head_lock;
struct strbuf buf = STRBUF_INIT;
+ struct strbuf err = STRBUF_INIT;
int fd;
- fd = hold_lock_file_for_update(&head_lock, head_file, LOCK_DIE_ON_ERROR);
+ fd = hold_lock_file_for_update(&head_lock, head_file, 0, &err);
+ if (fd < 0)
+ die("%s", err.buf);
strbuf_addf(&buf, "%s\n", head);
if (write_in_full(fd, buf.buf, buf.len) < 0)
die_errno(_("Could not write to %s"), head_file);
if (commit_lock_file(&head_lock) < 0)
die(_("Error wrapping up %s."), head_file);
+ strbuf_release(&err);
}
static int reset_for_rollback(const unsigned char *sha1)
@@ -935,9 +942,12 @@ static void save_todo(struct commit_list *todo_list, struct replay_opts *opts)
const char *todo_file = git_path(SEQ_TODO_FILE);
static struct lock_file todo_lock;
struct strbuf buf = STRBUF_INIT;
+ struct strbuf err = STRBUF_INIT;
int fd;
- fd = hold_lock_file_for_update(&todo_lock, todo_file, LOCK_DIE_ON_ERROR);
+ fd = hold_lock_file_for_update(&todo_lock, todo_file, 0, &err);
+ if (fd < 0)
+ die("%s", err.buf);
if (format_todo(&buf, todo_list, opts) < 0)
die(_("Could not format %s."), todo_file);
if (write_in_full(fd, buf.buf, buf.len) < 0) {
@@ -949,6 +959,7 @@ static void save_todo(struct commit_list *todo_list, struct replay_opts *opts)
die(_("Error wrapping up %s."), todo_file);
}
strbuf_release(&buf);
+ strbuf_release(&err);
}
static void save_opts(struct replay_opts *opts)
diff --git a/shallow.c b/shallow.c
index cdd0775146..4a30a77c61 100644
--- a/shallow.c
+++ b/shallow.c
@@ -259,10 +259,13 @@ void setup_alternate_shallow(struct lock_file *shallow_lock,
const struct sha1_array *extra)
{
struct strbuf sb = STRBUF_INIT;
+ struct strbuf err = STRBUF_INIT;
int fd;
- fd = hold_lock_file_for_update(shallow_lock, git_path("shallow"),
- LOCK_DIE_ON_ERROR);
+ fd = hold_lock_file_for_update(shallow_lock,
+ git_path("shallow"), 0, &err);
+ if (fd < 0)
+ die("%s", err.buf);
check_shallow_file_for_update();
if (write_shallow_commits(&sb, 0, extra)) {
if (write_in_full(fd, sb.buf, sb.len) != sb.len)
@@ -276,6 +279,7 @@ void setup_alternate_shallow(struct lock_file *shallow_lock,
*/
*alternate_shallow_file = "";
strbuf_release(&sb);
+ strbuf_release(&err);
}
static int advertise_shallow_grafts_cb(const struct commit_graft *graft, void *cb)
@@ -301,6 +305,7 @@ void prune_shallow(int show_only)
{
static struct lock_file shallow_lock;
struct strbuf sb = STRBUF_INIT;
+ struct strbuf err = STRBUF_INIT;
int fd;
if (show_only) {
@@ -308,8 +313,10 @@ void prune_shallow(int show_only)
strbuf_release(&sb);
return;
}
- fd = hold_lock_file_for_update(&shallow_lock, git_path("shallow"),
- LOCK_DIE_ON_ERROR);
+ fd = hold_lock_file_for_update(&shallow_lock,
+ git_path("shallow"), 0, &err);
+ if (fd < 0)
+ die("%s", err.buf);
check_shallow_file_for_update();
if (write_shallow_commits_1(&sb, 0, NULL, SEEN_ONLY)) {
if (write_in_full(fd, sb.buf, sb.len) != sb.len)
@@ -321,6 +328,7 @@ void prune_shallow(int show_only)
rollback_lock_file(&shallow_lock);
}
strbuf_release(&sb);
+ strbuf_release(&err);
}
struct trace_key trace_shallow = TRACE_KEY_INIT(SHALLOW);