mirror of
https://github.com/JakeHillion/drgn.git
synced 2024-12-22 17:23:06 +00:00
libdrgn: indicate finder lookup failure with special error
Currently, finders indicate a non-fatal lookup error by setting the type member to NULL. This won't work when we replace the symbol finder with an object finder (which shouldn't modify the object on failure). Instead, use a static error for this purpose.
This commit is contained in:
parent
0cb77b303c
commit
62ff4e1dba
@ -123,6 +123,16 @@ struct drgn_error {
|
||||
*/
|
||||
extern struct drgn_error drgn_enomem;
|
||||
|
||||
/**
|
||||
* Non-fatal lookup @ref drgn_error.
|
||||
*
|
||||
* This has a code of @ref DRGN_ERROR_LOOKUP. It should be returned from a @ref
|
||||
* drgn_type_find_fn() or @ref drgn_symbol_find_fn() to indicate that the entity
|
||||
* in question could not be found. It does not need to be passed to @ref
|
||||
* drgn_error_destroy() (but it can be).
|
||||
*/
|
||||
extern struct drgn_error drgn_not_found;
|
||||
|
||||
/**
|
||||
* Create a @ref drgn_error.
|
||||
*
|
||||
@ -966,9 +976,6 @@ bool drgn_filename_matches(const char *haystack, const char *needle);
|
||||
/**
|
||||
* Callback for finding a type.
|
||||
*
|
||||
* If the type is found, this should fill in @p ret and return @c NULL. If not,
|
||||
* this should set <tt>ret->type</tt> to @c NULL and return @c NULL.
|
||||
*
|
||||
* @param[in] kind Kind of type.
|
||||
* @param[in] name Name of type (or tag, for structs, unions, and enums). This
|
||||
* is @em not null-terminated.
|
||||
@ -977,7 +984,9 @@ bool drgn_filename_matches(const char *haystack, const char *needle);
|
||||
* should be matched with @ref drgn_filename_matches().
|
||||
* @param[in] arg Argument passed to @ref drgn_program_add_type_finder().
|
||||
* @param[out] ret Returned type.
|
||||
* @return @c NULL on success, non-@c NULL on error.
|
||||
* @return @c NULL on success, non-@c NULL on error. In particular, if the type
|
||||
* is not found, this should return &@ref drgn_not_found; any other errors are
|
||||
* considered fatal.
|
||||
*/
|
||||
typedef struct drgn_error *
|
||||
(*drgn_type_find_fn)(enum drgn_type_kind kind, const char *name,
|
||||
@ -1068,9 +1077,6 @@ struct drgn_symbol {
|
||||
/**
|
||||
* Callback for finding a symbol.
|
||||
*
|
||||
* If the symbol is found, this should fill in @p ret and return @c NULL. If
|
||||
* not, this should set <tt>ret->type</tt> to @c NULL and return @c NULL.
|
||||
*
|
||||
* @param[in] name Name of symbol. This is @em not null-terminated.
|
||||
* @param[in] name_len Length of @p name.
|
||||
* @param[in] filename Filename containing the symbol definition or @c NULL.
|
||||
@ -1078,7 +1084,9 @@ struct drgn_symbol {
|
||||
* @param[in] flags Flags indicating what kind of object to look for.
|
||||
* @param[in] arg Argument passed to @ref drgn_program_add_symbol_finder().
|
||||
* @param[out] ret Returned symbol.
|
||||
* @return @c NULL on success, non-@c NULL on error.
|
||||
* @return @c NULL on success, non-@c NULL on error. In particular, if the
|
||||
* symbol is not found, this should return &@ref drgn_not_found; any other
|
||||
* errors are considered fatal.
|
||||
*/
|
||||
typedef struct drgn_error *
|
||||
(*drgn_symbol_find_fn)(const char *name, size_t name_len, const char *filename,
|
||||
|
@ -1402,8 +1402,7 @@ struct drgn_error *drgn_dwarf_type_find(enum drgn_type_kind kind,
|
||||
}
|
||||
if (err && err->code != DRGN_ERROR_STOP)
|
||||
return err;
|
||||
ret->type = NULL;
|
||||
return NULL;
|
||||
return &drgn_not_found;
|
||||
}
|
||||
|
||||
static struct drgn_error *
|
||||
@ -1521,8 +1520,7 @@ drgn_dwarf_symbol_find(const char *name, size_t name_len, const char *filename,
|
||||
}
|
||||
if (err && err->code != DRGN_ERROR_STOP)
|
||||
return err;
|
||||
ret->type = NULL;
|
||||
return NULL;
|
||||
return &drgn_not_found;
|
||||
}
|
||||
|
||||
struct drgn_error *
|
||||
|
@ -17,6 +17,11 @@ LIBDRGN_PUBLIC struct drgn_error drgn_enomem = {
|
||||
.message = "cannot allocate memory",
|
||||
};
|
||||
|
||||
LIBDRGN_PUBLIC struct drgn_error drgn_not_found = {
|
||||
.code = DRGN_ERROR_LOOKUP,
|
||||
.message = "not found",
|
||||
};
|
||||
|
||||
struct drgn_error drgn_stop = {
|
||||
.code = DRGN_ERROR_STOP,
|
||||
.message = "stop iteration",
|
||||
|
@ -221,8 +221,8 @@ static struct drgn_error *py_type_find_fn(enum drgn_type_kind kind,
|
||||
goto out_name_obj;
|
||||
}
|
||||
if (type_obj == Py_None) {
|
||||
ret->type = NULL;
|
||||
goto out;
|
||||
err = &drgn_not_found;
|
||||
goto out_type_obj;
|
||||
}
|
||||
if (!PyObject_TypeCheck(type_obj, &DrgnType_type)) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
@ -238,7 +238,6 @@ static struct drgn_error *py_type_find_fn(enum drgn_type_kind kind,
|
||||
|
||||
ret->type = ((DrgnType *)type_obj)->type;
|
||||
ret->qualifiers = ((DrgnType *)type_obj)->qualifiers;
|
||||
out:
|
||||
err = NULL;
|
||||
out_type_obj:
|
||||
Py_DECREF(type_obj);
|
||||
@ -311,8 +310,8 @@ static struct drgn_error *py_symbol_find_fn(const char *name, size_t name_len,
|
||||
goto out_flags_obj;
|
||||
}
|
||||
if (sym_obj == Py_None) {
|
||||
ret->type = NULL;
|
||||
goto out;
|
||||
err = &drgn_not_found;
|
||||
goto out_sym_obj;
|
||||
}
|
||||
if (!PyObject_TypeCheck(sym_obj, &Symbol_type)) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
@ -327,7 +326,6 @@ static struct drgn_error *py_symbol_find_fn(const char *name, size_t name_len,
|
||||
}
|
||||
|
||||
*ret = ((Symbol *)sym_obj)->sym;
|
||||
out:
|
||||
err = NULL;
|
||||
out_sym_obj:
|
||||
Py_DECREF(sym_obj);
|
||||
|
@ -91,9 +91,7 @@ struct drgn_error *drgn_symbol_index_find(struct drgn_symbol_index *sindex,
|
||||
while (finder) {
|
||||
err = finder->fn(name, name_len, filename, flags, finder->arg,
|
||||
ret);
|
||||
if (err)
|
||||
return err;
|
||||
if (ret->type) {
|
||||
if (!err) {
|
||||
if (ret->kind == DRGN_SYMBOL_ENUMERATOR ||
|
||||
ret->kind == DRGN_SYMBOL_CONSTANT) {
|
||||
if (!(flags & DRGN_FIND_OBJECT_CONSTANT))
|
||||
@ -113,6 +111,8 @@ struct drgn_error *drgn_symbol_index_find(struct drgn_symbol_index *sindex,
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
if (err != &drgn_not_found)
|
||||
return err;
|
||||
finder = finder->next;
|
||||
}
|
||||
|
||||
|
@ -225,9 +225,8 @@ static void default_primitive_types_init(void)
|
||||
}
|
||||
|
||||
/*
|
||||
* Like @ref drgn_type_index_find_parsed(), but sets <tt>ret->type</tt> to NULL
|
||||
* and returns @c NULL if the type is not found instead of returning a @ref
|
||||
* DRGN_ERROR_LOOKUP error.
|
||||
* Like @ref drgn_type_index_find_parsed(), but returns
|
||||
* <tt>&drgn_error_not_found</tt> instead of a more informative error message.
|
||||
*/
|
||||
static struct drgn_error *
|
||||
drgn_type_index_find_parsed_internal(struct drgn_type_index *tindex,
|
||||
@ -242,19 +241,18 @@ drgn_type_index_find_parsed_internal(struct drgn_type_index *tindex,
|
||||
while (finder) {
|
||||
err = finder->fn(kind, name, name_len, filename, finder->arg,
|
||||
ret);
|
||||
if (err)
|
||||
return err;
|
||||
if (ret->type) {
|
||||
if (!err) {
|
||||
if (drgn_type_kind(ret->type) != kind) {
|
||||
return drgn_error_create(DRGN_ERROR_TYPE,
|
||||
"type find callback returned wrong kind of type");
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
if (err != &drgn_not_found)
|
||||
return err;
|
||||
finder = finder->next;
|
||||
}
|
||||
ret->type = NULL;
|
||||
return NULL;
|
||||
return &drgn_not_found;
|
||||
}
|
||||
|
||||
struct drgn_error *
|
||||
@ -286,12 +284,11 @@ drgn_type_index_find_primitive(struct drgn_type_index *tindex,
|
||||
strlen(spellings[i]),
|
||||
NULL,
|
||||
&qualified_type);
|
||||
if (err) {
|
||||
return err;
|
||||
} else if (qualified_type.type &&
|
||||
drgn_type_primitive(qualified_type.type) == type) {
|
||||
if (!err && drgn_type_primitive(qualified_type.type) == type) {
|
||||
*ret = qualified_type.type;
|
||||
goto out;
|
||||
} else if (err && err != &drgn_not_found) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
@ -373,10 +370,8 @@ drgn_type_index_find_parsed(struct drgn_type_index *tindex,
|
||||
|
||||
err = drgn_type_index_find_parsed_internal(tindex, kind, name, name_len,
|
||||
filename, ret);
|
||||
if (err)
|
||||
if (err != &drgn_not_found)
|
||||
return err;
|
||||
else if (ret->type)
|
||||
return NULL;
|
||||
|
||||
precision = name_len < INT_MAX ? (int)name_len : INT_MAX;
|
||||
if (filename) {
|
||||
|
Loading…
Reference in New Issue
Block a user