Skip to content

Commit

Permalink
Fix debug output in the dynamic linker.
Browse files Browse the repository at this point in the history
This provides a mini-printf implementation that reduces the
size of the dynamic linker by 25 KB, by preventing the drag of
formatting-related routines from the C library.

Also allow traces to be sent to the log, instead of stdout.

NOTE: You now need to modify Android.mk to enable/disable debug
      output.
  • Loading branch information
digit-android committed Feb 11, 2010
1 parent e100f52 commit 5c73464
Show file tree
Hide file tree
Showing 7 changed files with 809 additions and 15 deletions.
5 changes: 5 additions & 0 deletions linker/Android.mk
Expand Up @@ -4,6 +4,7 @@ include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
arch/$(TARGET_ARCH)/begin.S \
linker.c \
linker_format.c \
rt.c \
dlfcn.c \
debugger.c \
Expand Down Expand Up @@ -31,6 +32,10 @@ LOCAL_CFLAGS += -DPRELINK
LOCAL_CFLAGS += -DLINKER_TEXT_BASE=$(LINKER_TEXT_BASE)
LOCAL_CFLAGS += -DLINKER_AREA_SIZE=$(LINKER_AREA_SIZE)

# Set LINKER_DEBUG to either 1 or 0
#
LOCAL_CFLAGS += -DLINKER_DEBUG=0

# we need to access the Bionic private header <bionic_tls.h>
# in the linker; duplicate the HAVE_ARM_TLS_REGISTER definition
# from the libc build
Expand Down
29 changes: 29 additions & 0 deletions linker/README.TXT
Expand Up @@ -112,3 +112,32 @@ On x86, the lists of constructors and destructors are placed in special
sections named ".ctors" and ".dtors", and the DT_INIT / DT_FINI functions
are in charge of calling them explicitely.


Debugging:
----------

It is possible to enable debug output in the dynamic linker. To do so,
follow these steps:

1/ Modify the line in Android.mk that says:

LOCAL_CFLAGS += -DLINKER_DEBUG=0

Into the following:

LOCAL_CFLAGS += -DLINKER_DEBUG=1

2/ Force-rebuild the dynamic linker:

cd bionic/linker
mm -B

3/ Rebuild a new system image.

You can increase the verbosity of debug traces by defining the DEBUG
environment variable to a numeric value from 0 to 2. This will only
affect new processes being launched.

By default, traces are sent to logcat, with the "linker" tag. You can
change this to go to stdout instead by setting the definition of
LINKER_DEBUG_TO_LOG to 0 in "linker_debug.h"
3 changes: 2 additions & 1 deletion linker/dlfcn.c
Expand Up @@ -17,6 +17,7 @@
#include <pthread.h>
#include <stdio.h>
#include "linker.h"
#include "linker_format.h"

/* This file hijacks the symbols stubbed out in libdl.so. */

Expand Down Expand Up @@ -45,7 +46,7 @@ static pthread_mutex_t dl_lock = PTHREAD_MUTEX_INITIALIZER;

static void set_dlerror(int err)
{
snprintf(dl_err_buf, sizeof(dl_err_buf), "%s: %s", dl_errors[err],
format_buffer(dl_err_buf, sizeof(dl_err_buf), "%s: %s", dl_errors[err],
linker_get_error());
dl_err_str = (const char *)&dl_err_buf[0];
};
Expand Down
7 changes: 4 additions & 3 deletions linker/linker.c
Expand Up @@ -48,6 +48,7 @@

#include "linker.h"
#include "linker_debug.h"
#include "linker_format.h"

#include "ba.h"

Expand Down Expand Up @@ -142,7 +143,7 @@ static char tmp_err_buf[768];
static char __linker_dl_err_buf[768];
#define DL_ERR(fmt, x...) \
do { \
snprintf(__linker_dl_err_buf, sizeof(__linker_dl_err_buf), \
format_buffer(__linker_dl_err_buf, sizeof(__linker_dl_err_buf), \
"%s[%d]: " fmt, __func__, __LINE__, ##x); \
ERROR(fmt "\n", ##x); \
} while(0)
Expand Down Expand Up @@ -584,7 +585,7 @@ static int open_library(const char *name)
return fd;

for (path = ldpaths; *path; path++) {
n = snprintf(buf, sizeof(buf), "%s/%s", *path, name);
n = format_buffer(buf, sizeof(buf), "%s/%s", *path, name);
if (n < 0 || n >= (int)sizeof(buf)) {
WARN("Ignoring very long library path: %s/%s\n", *path, name);
continue;
Expand All @@ -593,7 +594,7 @@ static int open_library(const char *name)
return fd;
}
for (path = sopaths; *path; path++) {
n = snprintf(buf, sizeof(buf), "%s/%s", *path, name);
n = format_buffer(buf, sizeof(buf), "%s/%s", *path, name);
if (n < 0 || n >= (int)sizeof(buf)) {
WARN("Ignoring very long library path: %s/%s\n", *path, name);
continue;
Expand Down
36 changes: 25 additions & 11 deletions linker/linker_debug.h
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2008 The Android Open Source Project
* Copyright (C) 2008-2010 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -31,12 +31,17 @@

#include <stdio.h>

/* WARNING: For linker debugging only.. Be careful not to leave any of
* this on when submitting back to repository */
#define LINKER_DEBUG 0
#define TRACE_DEBUG 0
#define DO_TRACE_LOOKUP 0
#define DO_TRACE_RELO 0
#ifndef LINKER_DEBUG
#error LINKER_DEBUG should be defined to either 1 or 0 in Android.mk
#endif

/* set LINKER_DEBUG_TO_LOG to 1 to send the logs to logcat,
* or 0 to use stdout instead.
*/
#define LINKER_DEBUG_TO_LOG 1
#define TRACE_DEBUG 1
#define DO_TRACE_LOOKUP 1
#define DO_TRACE_RELO 1
#define TIMING 0
#define STATS 0
#define COUNT_PAGES 0
Expand All @@ -59,12 +64,21 @@
* corruption when the linker uses printf().
*/
#if LINKER_DEBUG
#include "linker_format.h"
extern int debug_verbosity;
#warning "*** LINKER IS USING printf(); DO NOT CHECK THIS IN ***"
#define _PRINTVF(v,f,x...) \
do { \
(debug_verbosity > (v)) && (printf(x), ((f) && fflush(stdout))); \
#if LINKER_DEBUG_TO_LOG
extern int format_log(int, const char *, const char *, ...);
#define _PRINTVF(v,f,x...) \
do { \
if (debug_verbosity > (v)) format_log(5-(v),"linker",x); \
} while (0)
#else /* !LINKER_DEBUG_TO_LOG */
extern int format_fd(int, const char *, ...);
#define _PRINTVF(v,f,x...) \
do { \
if (debug_verbosity > (v)) format_fd(1, x); \
} while (0)
#endif /* !LINKER_DEBUG_TO_LOG */
#else /* !LINKER_DEBUG */
#define _PRINTVF(v,f,x...) do {} while(0)
#endif /* LINKER_DEBUG */
Expand Down

0 comments on commit 5c73464

Please sign in to comment.