diff options
author | Bartosz Nitka <niteria@gmail.com> | 2017-09-18 07:53:56 -0700 |
---|---|---|
committer | Bartosz Nitka <niteria@gmail.com> | 2017-09-18 09:17:31 -0700 |
commit | cdaf5f2027ea9678e9f92e9140c79da2daa78360 (patch) | |
tree | f5faf4681779da5f65352639fa85354c97b91c17 | |
parent | 2258a2936bbeebcf671e19e8d6408b3a611c329d (diff) | |
download | haskell-cdaf5f2027ea9678e9f92e9140c79da2daa78360.tar.gz |
[RTS] Add getObjectLoadStatus
This adds a function to the RTS linker API which lets the
user check the status of dynamically linked objects.
It was initially proposed by @afarmer in D2068.
It's useful for testing the linker and also for detecting retention
problems in production.
It takes a path, because it's easier to use path as key instead of producing
some stable handle.
It returns an enum instead of bool, because I see no reason for destroying
information. All the complexity is already out in the open, so there's
nothing to save the users from.
Test Plan: ./validate
Reviewers: simonmar, Phyx, bgamari, austin, erikd
Reviewed By: Phyx, bgamari
Subscribers: rwbarton, afarmer, thomie
Differential Revision: https://phabricator.haskell.org/D3963
-rw-r--r-- | includes/rts/Linker.h | 14 | ||||
-rw-r--r-- | rts/Linker.c | 24 | ||||
-rw-r--r-- | rts/LinkerInternals.h | 9 |
3 files changed, 38 insertions, 9 deletions
diff --git a/includes/rts/Linker.h b/includes/rts/Linker.h index 793195b3ab..298dc6a366 100644 --- a/includes/rts/Linker.h +++ b/includes/rts/Linker.h @@ -47,6 +47,20 @@ HsInt insertSymbol(pathchar* obj_name, char* key, void* data); /* lookup a symbol in the hash table */ void *lookupSymbol( char *lbl ); +/* See Linker.c Note [runtime-linker-phases] */ +typedef enum { + OBJECT_LOADED, + OBJECT_NEEDED, + OBJECT_RESOLVED, + OBJECT_UNLOADED, + OBJECT_DONT_RESOLVE, + OBJECT_NOT_LOADED /* The object was either never loaded or has been + fully unloaded */ +} OStatus; + +/* check object load status */ +OStatus getObjectLoadStatus( pathchar *path ); + /* delete an object from the pool */ HsInt unloadObj( pathchar *path ); diff --git a/rts/Linker.c b/rts/Linker.c index 18f2c6b958..30d7e87f92 100644 --- a/rts/Linker.c +++ b/rts/Linker.c @@ -1708,6 +1708,30 @@ HsInt purgeObj (pathchar *path) return r; } +static OStatus getObjectLoadStatus_ (pathchar *path) +{ + ObjectCode *o; + for (o = objects; o; o = o->next) { + if (0 == pathcmp(o->fileName, path)) { + return o->status; + } + } + for (o = unloaded_objects; o; o = o->next) { + if (0 == pathcmp(o->fileName, path)) { + return o->status; + } + } + return OBJECT_NOT_LOADED; +} + +OStatus getObjectLoadStatus (pathchar *path) +{ + ACQUIRE_LOCK(&linker_mutex); + OStatus r = getObjectLoadStatus_(path); + RELEASE_LOCK(&linker_mutex); + return r; +} + /* ----------------------------------------------------------------------------- * Sanity checking. For each ObjectCode, maintain a list of address ranges * which may be prodded during relocation, and abort if we try and write diff --git a/rts/LinkerInternals.h b/rts/LinkerInternals.h index 2e8491789d..dd17be0992 100644 --- a/rts/LinkerInternals.h +++ b/rts/LinkerInternals.h @@ -20,15 +20,6 @@ typedef void SymbolAddr; typedef char SymbolName; -/* See Linker.c Note [runtime-linker-phases] */ -typedef enum { - OBJECT_LOADED, - OBJECT_NEEDED, - OBJECT_RESOLVED, - OBJECT_UNLOADED, - OBJECT_DONT_RESOLVE -} OStatus; - /* Indication of section kinds for loaded objects. Needed by the GC for deciding whether or not a pointer on the stack is a code pointer. |