summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dwflpp.cxx84
-rw-r--r--dwflpp.h4
-rw-r--r--loc2c-test.c40
-rw-r--r--loc2c.c41
-rw-r--r--loc2c.h7
-rw-r--r--tapset/ioblock.stp9
-rw-r--r--tapset/nfs_proc.stp16
-rw-r--r--tapset/scsi.stp6
-rw-r--r--tapset/task.stp30
-rw-r--r--tapsets.cxx49
-rw-r--r--tapsets.h1
-rw-r--r--testsuite/systemtap.exelib/exelib.exp8
-rw-r--r--translate.cxx59
13 files changed, 262 insertions, 92 deletions
diff --git a/dwflpp.cxx b/dwflpp.cxx
index b2532246..17bce608 100644
--- a/dwflpp.cxx
+++ b/dwflpp.cxx
@@ -63,16 +63,16 @@ using namespace __gnu_cxx;
static string TOK_KERNEL("kernel");
-dwflpp::dwflpp(systemtap_session & session, const string& user_module):
+dwflpp::dwflpp(systemtap_session & session, const string& name, bool kernel_p):
sess(session), module(NULL), module_bias(0), mod_info(NULL),
module_start(0), module_end(0), cu(NULL), dwfl(NULL),
module_dwarf(NULL), function(NULL), blacklist_enabled(false),
pc_cached_scopes(0), num_cached_scopes(0), cached_scopes(NULL)
{
- if (user_module.empty())
- setup_kernel();
+ if (kernel_p)
+ setup_kernel(name);
else
- setup_user(user_module);
+ setup_user(name);
}
@@ -250,8 +250,32 @@ dwflpp::function_name_final_match(const string& pattern)
}
+static const char *offline_search_modname = NULL;
+static int offline_search_match_p = 0;
+
+static int dwfl_report_offline_predicate (const char* modname, const char* filename)
+{
+ if (pending_interrupts)
+ return -1;
+
+ if (offline_search_match_p)
+ return -1;
+
+ assert (offline_search_modname);
+
+ /* Reject mismatching module names */
+ if (strcmp(modname, offline_search_modname))
+ return 0;
+ else
+ {
+ offline_search_match_p ++;
+ return 1;
+ }
+}
+
+
void
-dwflpp::setup_kernel(bool debuginfo_needed)
+dwflpp::setup_kernel(const string& name, bool debuginfo_needed)
{
// XXX: See also translate.cxx:emit_symbol_data
@@ -289,21 +313,31 @@ dwflpp::setup_kernel(bool debuginfo_needed)
else
elfutils_kernel_path = sess.kernel_build_tree;
+ offline_search_modname = name.c_str();
+ offline_search_match_p = 0;
int rc = dwfl_linux_kernel_report_offline (dwfl,
elfutils_kernel_path.c_str(),
&dwfl_report_offline_predicate);
+ offline_search_modname = NULL;
+
+ (void) rc; /* Ignore since the predicate probably returned -1 at some point,
+ And libdwfl interprets that as "whole query failed" rather than
+ "found it already, stop looking". */
- if (debuginfo_needed) {
- if (rc) {
- // Suggest a likely kernel dir to find debuginfo rpm for
- string dir = string("/lib/modules/" + sess.kernel_release );
- find_debug_rpms(sess, dir.c_str());
+ /* But we still need to check whether the module was itself found. One could
+ do an iterate_modules() search over the resulting dwfl and count hits. Or
+ one could rely on the match_p flag being set just before. */
+ if (! offline_search_match_p)
+ {
+ if (debuginfo_needed) {
+ // Suggest a likely kernel dir to find debuginfo rpm for
+ string dir = string("/lib/modules/" + sess.kernel_release );
+ find_debug_rpms(sess, dir.c_str());
+ }
+ throw semantic_error (string("missing ") + sess.architecture +
+ string(" kernel/module debuginfo under '") +
+ sess.kernel_build_tree + string("'"));
}
- dwfl_assert (string("missing ") + sess.architecture +
- string(" kernel/module debuginfo under '") +
- sess.kernel_build_tree + string("'"),
- rc);
- }
// XXX: it would be nice if we could do a single
// ..._report_offline call for an entire systemtap script, so
@@ -1415,6 +1449,24 @@ dwflpp::translate_location(struct obstack *pool,
struct location **tail,
const target_symbol *e)
{
+
+ /* DW_AT_data_member_location, can be either constant offsets
+ (struct member fields), or full blown location expressions. */
+ if (dwarf_whatattr (attr) == DW_AT_data_member_location)
+ {
+ unsigned int form = dwarf_whatform (attr);
+ if (form == DW_FORM_data1 || form == DW_FORM_data2
+ || form == DW_FORM_sdata || form == DW_FORM_udata)
+ {
+ Dwarf_Sword off;
+ if (dwarf_formsdata (attr, &off) != 0)
+ throw semantic_error (string ("dwarf_formsdata failed, ")
+ + string (dwarf_errmsg (-1)), e->tok);
+ c_translate_add_offset (pool, 1, NULL, off, tail);
+ return *tail;
+ }
+ }
+
Dwarf_Op *expr;
size_t len;
@@ -1436,7 +1488,7 @@ dwflpp::translate_location(struct obstack *pool,
default: /* Shouldn't happen. */
case -1:
- throw semantic_error (string ("dwarf_getlocation_addr failed") +
+ throw semantic_error (string ("dwarf_getlocation_addr failed, ") +
string (dwarf_errmsg (-1)),
e->tok);
}
diff --git a/dwflpp.h b/dwflpp.h
index ec6c5a0c..d6d97cd0 100644
--- a/dwflpp.h
+++ b/dwflpp.h
@@ -166,7 +166,7 @@ struct dwflpp
std::string cu_name;
std::string function_name;
- dwflpp(systemtap_session & session, const std::string& user_module="");
+ dwflpp(systemtap_session & session, const std::string& user_module, bool kernel_p);
~dwflpp();
void get_module_dwarf(bool required = false, bool report = true);
@@ -280,7 +280,7 @@ private:
Dwarf * module_dwarf;
Dwarf_Die * function;
- void setup_kernel(bool debuginfo_needed = true);
+ void setup_kernel(const std::string& module_name, bool debuginfo_needed = true);
void setup_user(const std::string& module_name, bool debuginfo_needed = true);
typedef std::map<Dwarf*, std::vector<Dwarf_Die>*> module_cu_cache_t;
diff --git a/loc2c-test.c b/loc2c-test.c
index 01edc805..688f4a8b 100644
--- a/loc2c-test.c
+++ b/loc2c-test.c
@@ -214,10 +214,35 @@ handle_variable (Dwarf_Die *scopes, int nscopes, int out,
}
else
{
- locexpr = get_location (cubias, pc, &attr_mem, &locexpr_len);
- c_translate_location (&pool, NULL, NULL, NULL,
- 1, cubias, pc, locexpr, locexpr_len,
- &tail, NULL);
+ /* We are expection a block, constant or loclistptr. */
+ unsigned int form = dwarf_whatform (&attr_mem);
+ Dwarf_Sword off;
+ switch (form)
+ {
+ /* constant */
+ case DW_FORM_data1:
+ case DW_FORM_data2:
+ case DW_FORM_sdata:
+ case DW_FORM_udata:
+ if (dwarf_formsdata (&attr_mem, &off) != 0)
+ error (2, 0, _("Bad offset for %s %s: %s"),
+ typetag == DW_TAG_union_type ? "union" : "struct",
+ dwarf_diename_integrate (die) ?: "<anonymous>",
+ dwarf_errmsg (-1));
+ if (off != 0)
+ c_translate_add_offset (&pool, 1,
+ dwarf_diename_integrate (die)
+ ?: "", off, &tail);
+ break;
+
+ default:
+ locexpr = get_location (cubias, pc, &attr_mem,
+ &locexpr_len);
+ c_translate_location (&pool, NULL, NULL, NULL,
+ 1, cubias, pc, locexpr, locexpr_len,
+ &tail, NULL);
+ break;
+ }
}
++fields;
break;
@@ -378,6 +403,9 @@ static void
print_vars (unsigned int indent, Dwarf_Die *die)
{
Dwarf_Die child;
+ Dwarf_Attribute attr_mem;
+ Dwarf_Die typedie_mem;
+ Dwarf_Die *typedie;
if (dwarf_child (die, &child) == 0)
do
switch (dwarf_tag (&child))
@@ -387,9 +415,7 @@ print_vars (unsigned int indent, Dwarf_Die *die)
printf ("%*s%-30s[%6" PRIx64 "]", indent, "",
dwarf_diename (&child),
(uint64_t) dwarf_dieoffset (&child));
- Dwarf_Attribute attr_mem;
- Dwarf_Die typedie_mem;
- Dwarf_Die *typedie = dwarf_formref_die
+ typedie = dwarf_formref_die
(dwarf_attr_integrate (&child, DW_AT_type, &attr_mem),
&typedie_mem);
print_type (typedie, '\t');
diff --git a/loc2c.c b/loc2c.c
index 7cae16cd..5f4e4495 100644
--- a/loc2c.c
+++ b/loc2c.c
@@ -251,9 +251,11 @@ translate (struct obstack *pool, int indent, Dwarf_Addr addrbias,
break;
case DW_OP_drop:
- POP (ignore);
- emit ("%*s/* drop " STACKFMT "*/\n", indent * 2, "", ignore);
- break;
+ {
+ POP (ignore);
+ emit ("%*s/* drop " STACKFMT "*/\n", indent * 2, "", ignore);
+ break;
+ }
case DW_OP_pick:
sp = expr[i].number;
@@ -622,7 +624,7 @@ location_relative (struct obstack *pool,
const Dwarf_Op *expr, size_t len, Dwarf_Addr address,
struct location **input, Dwarf_Attribute *fb_attr)
{
- Dwarf_Sword *stack;
+ Dwarf_Sword *stack = NULL;
unsigned int stack_depth = 0, max_stack = 0;
inline void deepen (void)
{
@@ -1667,7 +1669,38 @@ c_translate_pointer_store (struct obstack *pool, int indent,
}
+/* Translate a fragment to add an offset to the currently calculated
+ address of the input location. Used for struct fields. Only works
+ when location is already an actual base address.
+*/
+
+void
+c_translate_add_offset (struct obstack *pool, int indent, const char *comment,
+ Dwarf_Sword off, struct location **input)
+{
+ indent++;
+ if (comment == NULL || comment[0] == '\0')
+ comment = "field offset";
+ switch ((*input)->type)
+ {
+ case loc_address:
+ obstack_printf (pool, "%*saddr += " SFORMAT "; // %s\n",
+ indent * 2 + 2, "", off, comment);
+ *input = (*input)->next = new_synthetic_loc (pool, *input, false);
+ break;
+ case loc_register:
+ FAIL (*input, N_("cannot add offset of object in register"));
+ break;
+ case loc_noncontiguous:
+ FAIL (*input, N_("cannot add offset of noncontiguous object"));
+ break;
+
+ default:
+ abort ();
+ break;
+ }
+}
/* Determine the element stride of an array type. */
static Dwarf_Word
diff --git a/loc2c.h b/loc2c.h
index 0ad5ae99..eb1f39d6 100644
--- a/loc2c.h
+++ b/loc2c.h
@@ -85,6 +85,13 @@ c_translate_pointer_store (struct obstack *pool, int indent,
Dwarf_Die *typedie, struct location **input,
const char *rvalue);
+/* Translate a fragment to add an offset to the currently calculated
+ address of the input location. Used for struct fields. Only works
+ when location is already an actual base address. */
+void
+c_translate_add_offset (struct obstack *pool, int indent, const char *comment,
+ Dwarf_Sword off, struct location **input);
+
/* Translate a C fragment for a direct argument VALUE. On errors, call FAIL,
which should not return. Any later errors will use FAIL and FAIL_ARG from
this translate call. On success, return the fragment created. */
diff --git a/tapset/ioblock.stp b/tapset/ioblock.stp
index 4bf7ad92..bc64c425 100644
--- a/tapset/ioblock.stp
+++ b/tapset/ioblock.stp
@@ -47,9 +47,12 @@ function bio_rw_str(rw)
/* returns start sector */
function __bio_start_sect:long(bio:long)
%{ /* pure */
- struct bio *bio = (struct bio *)(long)THIS->bio;
- struct block_device *bi_bdev = bio? kread(&(bio->bi_bdev)) : NULL;
- struct hd_struct *bd_part = bi_bdev? kread(&(bi_bdev->bd_part)) : NULL;
+ struct bio *bio;
+ struct block_device *bi_bdev;
+ struct hd_struct *bd_part;
+ bio = (struct bio *)(long)THIS->bio;
+ bi_bdev = bio? kread(&(bio->bi_bdev)) : NULL;
+ bd_part = bi_bdev? kread(&(bi_bdev->bd_part)) : NULL;
if (bd_part == NULL)
THIS->__retvalue = -1;
else
diff --git a/tapset/nfs_proc.stp b/tapset/nfs_proc.stp
index 11463e9a..e3d9a78f 100644
--- a/tapset/nfs_proc.stp
+++ b/tapset/nfs_proc.stp
@@ -84,12 +84,18 @@ function get_prot_from_client:long(clnt:long) %{ /* pure */
1:get proto
*/
function __i2n_ip_proto :long(dir:long,index:long) %{ /* pure */
- int index = (int) (THIS->index);
- struct inode * dir = (struct inode *)(uintptr_t)(THIS->dir);
- struct rpc_clnt * clnt = NFS_CLIENT(dir); /* FIXME: deref hazard! */
- struct rpc_xprt * cl_xprt = kread(&(clnt->cl_xprt));
+ int index;
+ struct inode * dir;
+ struct rpc_clnt * clnt;
+ struct rpc_xprt * cl_xprt;
+ struct sockaddr_in *addr;
+
+ index = (int) (THIS->index);
+ dir = (struct inode *)(uintptr_t)(THIS->dir);
+ clnt = NFS_CLIENT(dir); /* FIXME: deref hazard! */
+ cl_xprt = kread(&(clnt->cl_xprt));
/* sockaddr_storage is used since 2.6.19. Need cast*/
- struct sockaddr_in *addr = (struct sockaddr_in *)&(cl_xprt->addr);
+ addr = (struct sockaddr_in *)&(cl_xprt->addr);
if(index == 0) {
if (kread(&(addr->sin_family)) == AF_INET) {
diff --git a/tapset/scsi.stp b/tapset/scsi.stp
index e1457739..5758f315 100644
--- a/tapset/scsi.stp
+++ b/tapset/scsi.stp
@@ -130,8 +130,10 @@ function scsi_timer_pending:long(var:long)
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
THIS->__retvalue = timer_pending(&cmd->eh_timeout); /* FIXME: deref hazard! */
#else
- struct request *req = (struct request *)kread(&cmd->request);
- struct request_queue *rq = (struct request_queue *)kread(&req->q);
+ struct request *req;
+ struct request_queue *rq;
+ req = (struct request *)kread(&cmd->request);
+ rq = (struct request_queue *)kread(&req->q);
THIS->__retvalue = timer_pending(&rq->timeout); /* FIXME: deref hazard! */
CATCH_DEREF_FAULT();
#endif
diff --git a/tapset/task.stp b/tapset/task.stp
index f1a10b0a..1f4e0e6f 100644
--- a/tapset/task.stp
+++ b/tapset/task.stp
@@ -189,10 +189,13 @@ function task_cpu:long (task:long)
function task_open_file_handles:long (task:long)
%( kernel_v >= "2.6.15" %?
%{ /* pure */
- struct task_struct *t = (struct task_struct *)(long)THIS->task;
- struct files_struct *fs = kread(&(t->files));
- struct fdtable *f = kread(&(fs->fdt));
unsigned int count=0, fd, max;
+ struct task_struct *t;
+ struct files_struct *fs;
+ struct fdtable *f;
+ t = (struct task_struct *)(long)THIS->task;
+ fs = kread(&(t->files));
+ f = kread(&(fs->fdt));
rcu_read_lock();
max = kread(&(f->max_fds));
for (fd = 0; fd < max; fd++) {
@@ -205,9 +208,11 @@ function task_open_file_handles:long (task:long)
%}
%:
%{ /* pure */
- struct task_struct *t = (struct task_struct *)(long)THIS->task;
- struct files_struct *f = kread(&(t->files));
unsigned int count=0, fd, max;
+ struct task_struct *t;
+ struct files_struct *f;
+ t = (struct task_struct *)(long)THIS->task;
+ f = kread(&(t->files));
rcu_read_lock();
max = kread(&(f->max_fds));
for (fd = 0; fd < max; fd++) {
@@ -225,9 +230,12 @@ function task_open_file_handles:long (task:long)
function task_max_file_handles:long (task:long)
%( kernel_v >= "2.6.15" %?
%{ /* pure */
- struct task_struct *t = (struct task_struct *)(long)THIS->task;
- struct files_struct *fs = kread (&(t->files));
- struct fdtable *f = kread(&(fs->fdt));
+ struct task_struct *t;
+ struct files_struct *fs;
+ struct fdtable *f;
+ t = (struct task_struct *)(long)THIS->task;
+ fs = kread (&(t->files));
+ f = kread(&(fs->fdt));
rcu_read_lock();
THIS->__retvalue = kread(&(f->max_fds));
rcu_read_unlock();
@@ -235,8 +243,10 @@ function task_max_file_handles:long (task:long)
%}
%:
%{ /* pure */
- struct task_struct *t = (struct task_struct *)(long)THIS->task;
- struct files_struct *f = kread(&(t->files));
+ struct task_struct *t;
+ struct files_struct *f;
+ t = (struct task_struct *)(long)THIS->task;
+ f = kread(&(t->files));
rcu_read_lock();
THIS->__retvalue = kread(&(f->max_fds));
rcu_read_unlock();
diff --git a/tapsets.cxx b/tapsets.cxx
index 766cb39f..6ef1e188 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -312,15 +312,6 @@ static bool null_die(Dwarf_Die *die)
}
-// PR 9941 introduces the need for a predicate
-
-int dwfl_report_offline_predicate (const char* modname, const char* filename)
-{
- if (pending_interrupts) { return -1; }
- return 1;
-}
-
-
enum
function_spec_type
{
@@ -601,34 +592,36 @@ struct dwarf_query : public base_query
struct dwarf_builder: public derived_probe_builder
{
- dwflpp *kern_dw;
+ map <string,dwflpp*> kern_dw;
map <string,dwflpp*> user_dw;
- dwarf_builder(): kern_dw(0) {}
+ dwarf_builder() {}
- dwflpp *get_kern_dw(systemtap_session& sess)
+ dwflpp *get_kern_dw(systemtap_session& sess, const string& module)
{
- if (!kern_dw)
- kern_dw = new dwflpp(sess);
- return kern_dw;
+ if (kern_dw.find(module) == kern_dw.end())
+ kern_dw[module] = new dwflpp(sess, module, true);
+ return kern_dw[module];
}
dwflpp *get_user_dw(systemtap_session& sess, const string& module)
{
if (user_dw.find(module) == user_dw.end())
- user_dw[module] = new dwflpp(sess, module);
+ user_dw[module] = new dwflpp(sess, module, false);
return user_dw[module];
}
/* NB: not virtual, so can be called from dtor too: */
void dwarf_build_no_more (bool verbose)
{
- if (kern_dw)
+ for (map<string,dwflpp*>::iterator udi = kern_dw.begin();
+ udi != kern_dw.end();
+ udi ++)
{
if (verbose)
- clog << "dwarf_builder releasing kernel dwflpp" << endl;
- delete kern_dw;
- kern_dw = 0;
+ clog << "dwarf_builder releasing kernel dwflpp " << udi->first << endl;
+ delete udi->second;
}
+ kern_dw.erase (kern_dw.begin(), kern_dw.end());
for (map<string,dwflpp*>::iterator udi = user_dw.begin();
udi != user_dw.end();
@@ -2721,7 +2714,7 @@ void dwarf_cast_expanding_visitor::visit_cast_op (cast_op* e)
if (module.find('/') == string::npos)
{
// kernel or kernel module target
- dw = db.get_kern_dw(s);
+ dw = db.get_kern_dw(s, module);
}
else
{
@@ -3453,11 +3446,13 @@ dwarf_builder::build(systemtap_session & sess,
dwflpp* dw = 0;
string module_name;
- if (has_null_param (parameters, TOK_KERNEL)
- || get_param (parameters, TOK_MODULE, module_name))
+ if (has_null_param (parameters, TOK_KERNEL))
+ {
+ dw = get_kern_dw(sess, "kernel");
+ }
+ else if (get_param (parameters, TOK_MODULE, module_name))
{
- // kernel or kernel module target
- dw = get_kern_dw(sess);
+ dw = get_kern_dw(sess, module_name);
}
else if (get_param (parameters, TOK_PROCESS, module_name))
{
@@ -5711,7 +5706,7 @@ tracepoint_builder::init_dw(systemtap_session& s)
if (s.verbose > 2)
clog << "Pass 2: using cached " << s.tracequery_path << endl;
- dw = new dwflpp(s, s.tracequery_path);
+ dw = new dwflpp(s, s.tracequery_path, false);
close(fd);
return true;
}
@@ -5736,7 +5731,7 @@ tracepoint_builder::init_dw(systemtap_session& s)
<< s.tracequery_path << "\"): " << strerror(errno) << endl;
}
- dw = new dwflpp(s, tracequery_ko);
+ dw = new dwflpp(s, tracequery_ko, false);
return true;
}
diff --git a/tapsets.h b/tapsets.h
index 7a74ad31..115f2ccf 100644
--- a/tapsets.h
+++ b/tapsets.h
@@ -15,7 +15,6 @@
void register_standard_tapsets(systemtap_session& sess);
std::vector<derived_probe_group*> all_session_groups(systemtap_session& s);
-int dwfl_report_offline_predicate (const char* modname, const char* filename);
void common_probe_entryfn_prologue (translator_output* o, std::string statestr,
std::string new_pp, bool overload_processing = true);
void common_probe_entryfn_epilogue (translator_output* o, bool overload_processing = true);
diff --git a/testsuite/systemtap.exelib/exelib.exp b/testsuite/systemtap.exelib/exelib.exp
index d3ade2b6..c4ca8fc0 100644
--- a/testsuite/systemtap.exelib/exelib.exp
+++ b/testsuite/systemtap.exelib/exelib.exp
@@ -95,10 +95,10 @@ foreach arch $arches {
set res [target_compile $testsrclib $testso executable $testlibflags]
if { $res != "" } {
verbose "target_compile for $testso failed: $res" 2
- fail "$libname compile $testsrclib"
+ fail "$libname compile [file tail $testsrclib]"
return
} else {
- pass "$libname compile $testsrclib"
+ pass "$libname compile [file tail $testsrclib]"
}
# seperate debuginfo before prelinking
@@ -147,10 +147,10 @@ foreach arch $arches {
set res [target_compile $testsrc $testexe executable $testexeflags]
if { $res != "" } {
verbose "target_compile for $testexe failed: $res" 2
- fail "$exename compile $testsrc"
+ fail "$exename compile [file tail $testsrc]"
return
} else {
- pass "$exename compile $testsrc"
+ pass "$exename compile [file tail $testsrc]"
}
if {$exedebug == "sep"} {
diff --git a/translate.cxx b/translate.cxx
index f4c2412b..ddd96938 100644
--- a/translate.cxx
+++ b/translate.cxx
@@ -4908,6 +4908,27 @@ dump_unwindsyms (Dwfl_Module *m,
// them with the runtime.
void emit_symbol_data_done (unwindsym_dump_context*, systemtap_session&);
+
+static set<string> offline_search_modules;
+static int dwfl_report_offline_predicate2 (const char* modname, const char* filename)
+{
+ if (pending_interrupts)
+ return -1;
+
+ if (offline_search_modules.empty())
+ return -1;
+
+ /* Reject mismatching module names */
+ if (offline_search_modules.find(modname) == offline_search_modules.end())
+ return 0;
+ else
+ {
+ offline_search_modules.erase(modname);
+ return 1;
+ }
+}
+
+
void
emit_symbol_data (systemtap_session& s)
{
@@ -4960,22 +4981,38 @@ emit_symbol_data (systemtap_session& s)
else
elfutils_kernel_path = s.kernel_build_tree;
+
+ // Set up our offline search for kernel modules. As in dwflpp.cxx,
+ // we don't want the offline search iteration to do a complete search
+ // of the kernel build tree, since that's wasteful.
+ offline_search_modules.erase (offline_search_modules.begin(),
+ offline_search_modules.end());
+ for (set<string>::iterator it = s.unwindsym_modules.begin();
+ it != s.unwindsym_modules.end();
+ it++)
+ {
+ string foo = *it;
+ if (foo[0] != '/') /* Omit user-space, since we're only using this for
+ kernel space offline searches. */
+ offline_search_modules.insert (foo);
+ }
+
int rc = dwfl_linux_kernel_report_offline (dwfl,
elfutils_kernel_path.c_str(),
- &dwfl_report_offline_predicate);
+ & dwfl_report_offline_predicate2);
+
+ (void) rc; // As in dwflpp.cxx, we ignore rc here.
+
dwfl_report_end (dwfl, NULL, NULL);
- if (rc == 0) // tolerate missing data; will warn user about it anyway
+ ptrdiff_t off = 0;
+ do
{
- ptrdiff_t off = 0;
- do
- {
- if (pending_interrupts) return;
- if (ctx.undone_unwindsym_modules.empty()) break;
- off = dwfl_getmodules (dwfl, &dump_unwindsyms, (void *) &ctx, 0);
- }
- while (off > 0);
- dwfl_assert("dwfl_getmodules", off == 0);
+ if (pending_interrupts) return;
+ if (ctx.undone_unwindsym_modules.empty()) break;
+ off = dwfl_getmodules (dwfl, &dump_unwindsyms, (void *) &ctx, 0);
}
+ while (off > 0);
+ dwfl_assert("dwfl_getmodules", off == 0);
dwfl_end(dwfl);