FAQ Search Today's Posts Mark Forums Read
» Video Reviews

» Linux Archive

Linux-archive is a website aiming to archive linux email lists and to make them easily accessible for linux users/developers.


» Sponsor

» Partners

» Sponsor

Go Back   Linux Archive > Redhat > Crash Utility

 
 
LinkBack Thread Tools
 
Old 02-07-2012, 07:32 PM
Dave Anderson
 
Default Add -C option for search

----- Original Message -----
> Hello Dave,
>
> I add a new option -C for sub-command search to display memory contents
> just before and after the search target. The number of the memory unit
> displayed is specified by -C.
>
> for example,
> crash> search -p -C 3 dddd
> 17b5100: dddddddddddddddd dddddddddddddddd dddddddddddddddd
> 17b5118: dddd cdcdcdcdcdcdcdcd cdcdcdcdcdcdcdcd
> 17b5130: cdcdcdcdcdcdcdcd
> --
> 85d04f818: 29 ffff88085d04f818 ffffea001d3f7e30
> 85d04f830: dddd 1000 ffff88085b48a000
> 85d04f848: ffff880876383b80
> --
> 8752cfec8: ddd9 dddb dddb
> 8752cfee0: dddd dddd dddf
> 8752cfef8: dddf
> --
> 8752cfed0: dddb dddb dddd
> 8752cfee8: dddd dddf dddf
> 8752cff00: dde1
> --
> crash>
>
>
> Thanks.
> Zhang Yanfei

Hello Zhang,

I'm going to NAK this patch for a few reasons.

First, for an option that will very rarely be used, it adds an
*enormous* amount of code -- the patch is almost 1000 lines long!
I mean you've almost re-written the whole memory-search subsystem!
And the code is not particularly easy to understand, and quite
frankly, I do not want to get stuck maintaining it.

Secondly, on a live system, even if the option is *not* used,
a simple "search -k" is 30% slower. I'm not sure why it's
so slow, although interestingly enough, when run on a dumpfile,
it's basically the same speed. It's weird -- you would expect
it to be faster on a live system...

Third, it can be done in a much simpler manner, and done without
affecting the "normal" course of events.

Basically you've got the six functions that need to be modified
to display the context memory before and after a "found" piece
of data, i.e., search_ulong(), search_ulong_p(), search_uint(),
search_uint_p(), search_ushort() and search_ushort_p().

What I suggest is that you do something like this in each of
the 6 relevant functions:

static ulong
search_ulong(ulong *bufptr, ulong addr, int longcnt, struct searchinfo *si)
{
int i, j;
+ ulong *bufstart = bufptr;
+ ulong *bufend = bufptr + longcnt;
ulong mask = si->s_parms.s_ulong.mask;
for (i = 0; i < longcnt; i++, bufptr++, addr += sizeof(long)) {
for (j = 0; j < si->vcnt; j++) {
- if (SEARCHMASK(*bufptr) == SEARCHMASK(si->s_parms.s_ulong.value[j]))
- fprintf(fp, "%lx: %lx
", addr, *bufptr);
+ if (SEARCHMASK(*bufptr) == SEARCHMASK(si->s_parms.s_ulong.value[j])) {
+ if (si->c_num)
+ display_with_pre_and_post(si, bufstart, bufend, addr, *bufptr);
+ else
+ fprintf(fp, "%lx: %lx
", addr, *bufptr);
+ }
}
return addr;
}

and then put all of your functionality in the display_with_pre_and_post()
function. In most cases, the data before and after the target data
will be located in the pre-read buffer. In cases where the extra data
is outside the pre-read buffer, then you can simply do an extra readmem()
to satisfy the request.

Please -- just keep it simple!

Thanks,
Dave

--
Crash-utility mailing list
Crash-utility@redhat.com
https://www.redhat.com/mailman/listinfo/crash-utility
 
Old 02-09-2012, 06:57 AM
zhangyanfei
 
Default Add -C option for search

Hello Dave,

I made a new patch to implement the -C option for search. This time the
patch is accomplished in a simple manner according to your advice.

Thanks.
Zhang Yanfei
>From 0cde596e587b2344948118c04ed7416d68ae5fe2 Mon Sep 17 00:00:00 2001
From: zhangyanfei <zhangyanfei@cn.fujitsu.com>
Date: Thu, 9 Feb 2012 15:32:11 +0800
Subject: [PATCH] Add option -C for sub-command search.

Signed-off-by: zhangyanfei <zhangyanfei@cn.fujitsu.com>
---
help.c | 5 +-
memory.c | 271 ++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++---
2 files changed, 261 insertions(+), 15 deletions(-)

diff --git a/help.c b/help.c
index f752283..d3317f4 100755
--- a/help.c
+++ b/help.c
@@ -2343,7 +2343,7 @@ char *help_search[] = {
"seach",
"search memory",
"[-s start] [ -[kKV] | -u | -p ] [-e end | -l length] [-m mask]
"
-" -[cwh] value ...",
+" [-C num] -[cwh] value ...",
" This command searches for a given value within a range of user virtual, kernel",
" virtual, or physical memory space. If no end nor length value is entered, ",
" then the search stops at the end of user virtual, kernel virtual, or physical",
@@ -2374,6 +2374,9 @@ char *help_search[] = {
" appropriate for the memory type specified.",
" -l length Length in bytes of address range to search.",
" -m mask Ignore the bits that are set in the hexadecimal mask value.",
+" -C num Also display memory contents just before and after value. The size",
+" of the memory displayed before(after) value is num * sizeof(value).",
+" Note, this option is ignored when -c is specified.",
" -c Search for character string values instead of unsigned longs. If",
" the string contains any space(s), it must be encompassed by double",
" quotes.",
diff --git a/memory.c b/memory.c
index 55a184b..6672770 100755
--- a/memory.c
+++ b/memory.c
@@ -87,6 +87,8 @@ struct meminfo { /* general purpose memory information structure */
struct searchinfo {
int mode;
int vcnt;
+ int c_num;
+ ulong memtype;
union {
/* default ulong search */
struct {
@@ -176,6 +178,8 @@ static int dump_page_lists(struct meminfo *);
static void dump_kmeminfo(void);
static int page_to_phys(ulong, physaddr_t *);
static void display_memory(ulonglong, long, ulong, int, void *);
+static int get_search_page(ulonglong, char *, struct searchinfo *);
+static void display_with_pre_and_post(void *, ulonglong, ulonglong, struct searchinfo *);
static ulong search_ulong(ulong *, ulong, int, struct searchinfo *);
static ulong search_uint(ulong *, ulong, int, struct searchinfo *);
static ulong search_ushort(ulong *, ulong, int, struct searchinfo *);
@@ -11617,7 +11621,7 @@ generic_get_kvaddr_ranges(struct vaddr_range *rp)
void
cmd_search(void)
{
- int i, c, ranges;
+ int i, c, ranges, c_num;
ulonglong start, end;
ulong mask, memtype, len;
ulong uvaddr_start, uvaddr_end;
@@ -11631,6 +11635,7 @@ cmd_search(void)

#define vaddr_overflow(ADDR) (BITS32() && ((ADDR) > 0xffffffffULL))

+ c_num = 0;
start = end = mask = sflag = pflag = Kflag = Vflag = memtype = len = 0;
kvaddr_start = kvaddr_end = 0;
uvaddr_start = UNINITIALIZED;
@@ -11668,7 +11673,7 @@ cmd_search(void)

searchinfo.mode = SEARCH_ULONG; /* default search */

- while ((c = getopt(argcnt, args, "l:ukKVps:e:v:m:hwc")) != EOF) {
+ while ((c = getopt(argcnt, args, "l:ukKVps:e:v:m:hwcC:")) != EOF) {
switch(c)
{
case 'u':
@@ -11769,6 +11774,10 @@ cmd_search(void)
searchinfo.mode = SEARCH_CHARS;
break;

+ case 'C':
+ c_num = dtoi(optarg, FAULT_ON_ERROR, NULL);
+ break;
+
default:
argerrs++;
break;
@@ -11790,6 +11799,8 @@ cmd_search(void)
if (argerrs || !sflag || !args[optind] || (len && end) || !memtype)
cmd_usage(pc->curcmd, SYNOPSIS);

+ searchinfo.memtype = memtype;
+
/*
* Verify starting address.
*/
@@ -11916,6 +11927,37 @@ cmd_search(void)
}
}

+ if (c_num) {
+ switch (searchinfo.mode)
+ {
+ case SEARCH_ULONG:
+ if (c_num > PAGESIZE()/sizeof(long)) {
+ error(INFO, "WARNING: too many numbers and"
+ " -C option is ignored
");
+ c_num = 0;
+ }
+ break;
+ case SEARCH_UINT:
+ if (c_num > PAGESIZE()/sizeof(int)) {
+ error(INFO, "WARNING: too many numbers and"
+ " -C option is ignored
");
+ c_num = 0;
+ }
+ break;
+ case SEARCH_USHORT:
+ if (c_num > PAGESIZE()/sizeof(short)) {
+ error(INFO, "WARNING: too many numbers and"
+ " -C option is ignored
");
+ c_num = 0;
+ }
+ break;
+ case SEARCH_CHARS:
+ error(INFO, "-C option ignored on string search
");
+ c_num = 0;
+ break;
+ }
+ }
+ searchinfo.c_num = c_num;

searchinfo.vcnt = 0;
while (args[optind]) {
@@ -12013,15 +12055,191 @@ cmd_search(void)

#define SEARCHMASK(X) ((X) | mask)

+static int
+get_search_page(ulonglong ppp, char *pagebuf, struct searchinfo *si)
+{
+ ulong page;
+ physaddr_t paddr;
+ ulong pp;
+ ulong memtype;
+
+ pp = (ulong)ppp;
+ memtype = si->memtype;
+
+ if (memtype == PHYSADDR) {
+ if (!phys_to_page(ppp, &page) ||
+ !readmem(ppp, PHYSADDR, pagebuf, PAGESIZE(),
+ "search page", RETURN_ON_ERROR|QUIET)) {
+ return 0;
+ }
+ return 1;
+ }
+
+ /*
+ * Keep it virtual for Xen hypervisor.
+ */
+ if (XEN_HYPER_MODE()) {
+ if (!readmem(pp, KVADDR, pagebuf, PAGESIZE(),
+ "search page", RETURN_ON_ERROR|QUIET)) {
+ return 0;
+ }
+ return 1;
+ }
+
+ switch (memtype)
+ {
+ case UVADDR:
+ if (!uvtop(CURRENT_CONTEXT(), pp, &paddr, 0) ||
+ !phys_to_page(paddr, &page)) {
+ return 0;
+ }
+ break;
+
+ case KVADDR:
+ if (!kvtop(CURRENT_CONTEXT(), pp, &paddr, 0) ||
+ !phys_to_page(paddr, &page)) {
+ return 0;
+ }
+ break;
+ }
+
+ if (!readmem(paddr, PHYSADDR, pagebuf, PAGESIZE(),
+ "search page", RETURN_ON_ERROR|QUIET)) {
+ return 0;
+ }
+
+ return 1;
+}
+
+#define print_addr(addr, si)
+do {
+ if (si->memtype == PHYSADDR)
+ fprintf(fp, "%llx: ", addr);
+ else
+ fprintf(fp, "%lx: ", (ulong)addr);
+} while (0);
+
+#define print_value(bufptr, offset, si)
+do {
+ switch(si->mode)
+ {
+ case SEARCH_ULONG:
+ fprintf(fp, "%lx ", *((ulong *)bufptr + offset));
+ break;
+ case SEARCH_UINT:
+ fprintf(fp, "%x ", *((uint *)bufptr + offset));
+ break;
+ case SEARCH_USHORT:
+ fprintf(fp, "%x ", *((ushort *)bufptr + offset));
+ break;
+ }
+} while (0);
+
+static void
+display_with_pre_and_post(void *bufptr, ulonglong addr_base, ulonglong addr, struct searchinfo *si)
+{
+ int cnt, cnt1, cnt2, wordcnt, exist;
+ int i, c_num, t, offset;
+ char *buf;
+ ulonglong pre_addr_base, post_addr_base, tmpaddr;
+
+ switch (si->mode)
+ {
+ case SEARCH_USHORT:
+ t = sizeof(ushort);
+ break;
+ case SEARCH_UINT:
+ t = sizeof(uint);
+ break;
+ case SEARCH_ULONG:
+ default:
+ t = sizeof(ulong);
+ break;
+ }
+
+ cnt = offset = 0;
+ cnt1 = (addr - addr_base) / t;
+ cnt2 = (PAGESIZE() - (addr - addr_base)) / t - 1;
+ wordcnt = PAGESIZE() / t;
+ exist = 0;
+ c_num = si->c_num;
+ pre_addr_base = post_addr_base = addr_base;
+
+ buf = GETBUF(PAGESIZE());
+
+ if (cnt1 < c_num && addr_base >= PAGESIZE()) { /* read pre-page */
+ pre_addr_base -= PAGESIZE();
+ exist = get_search_page(pre_addr_base, buf, si);
+ }
+
+ if (exist) {
+ cnt = cnt1 - c_num + wordcnt;
+ tmpaddr = pre_addr_base + cnt * t;
+ print_addr(tmpaddr, si);
+ for (i = cnt; i < wordcnt; i++)
+ print_value(buf, i, si);
+ } else {
+ if (cnt1 >= c_num) {
+ tmpaddr = addr - c_num * t;
+ print_addr(tmpaddr, si);
+ } else if (cnt1 != 0)
+ print_addr(addr_base, si);
+ }
+
+ cnt = cnt1 < c_num ? 0 : cnt1 - c_num;
+ for (i = cnt; i < cnt1; i++) {
+ offset = i - cnt1;
+ print_value(bufptr, offset, si);
+ }
+ if (exist || cnt1 != 0)
+ fprintf(fp, "
");
+
+ print_addr(addr, si);
+ print_value(bufptr, 0, si);
+
+ exist = 0;
+ if (cnt2 < c_num) { /* read post-page */
+ post_addr_base += PAGESIZE();
+ exist = get_search_page(post_addr_base, buf, si);
+ }
+
+ cnt = cnt2 < c_num ? cnt2 : c_num - 1;
+ for (i = 1; i <= cnt; i++)
+ print_value(bufptr, i, si);
+
+ if (cnt2 >= c_num) {
+ fprintf(fp, "
");
+ tmpaddr = addr + c_num * t;
+ print_addr(tmpaddr, si);
+ print_value(bufptr, c_num, si);
+ } else {
+ if (exist) {
+ cnt = c_num - cnt2 - 1;
+ for (i = 0; i < cnt; i++)
+ print_value(buf, i, si);
+ fprintf(fp, "
");
+ tmpaddr = post_addr_base + cnt * t;
+ print_addr(tmpaddr, si);
+ print_value(buf, cnt, si);
+ }
+ }
+ fprintf(fp, "
--
");
+}
+
static ulong
search_ulong(ulong *bufptr, ulong addr, int longcnt, struct searchinfo *si)
{
int i, j;
+ ulong addr_base = VIRTPAGEBASE(addr);
ulong mask = si->s_parms.s_ulong.mask;
for (i = 0; i < longcnt; i++, bufptr++, addr += sizeof(long)) {
for (j = 0; j < si->vcnt; j++) {
- if (SEARCHMASK(*bufptr) == SEARCHMASK(si->s_parms.s_ulong.value[j]))
- fprintf(fp, "%lx: %lx
", addr, *bufptr);
+ if (SEARCHMASK(*bufptr) == SEARCHMASK(si->s_parms.s_ulong.value[j])) {
+ if (si->c_num)
+ display_with_pre_and_post(bufptr, addr_base, addr, si);
+ else
+ fprintf(fp, "%lx: %lx
", addr, *bufptr);
+ }
}
}
return addr;
@@ -12032,11 +12250,16 @@ static ulonglong
search_ulong_p(ulong *bufptr, ulonglong addr, int longcnt, struct searchinfo *si)
{
int i, j;
+ ulonglong addr_base = PHYSPAGEBASE(addr);
ulong mask = si->s_parms.s_ulong.mask;
for (i = 0; i < longcnt; i++, bufptr++, addr += sizeof(long)) {
for (j = 0; j < si->vcnt; j++) {
- if (SEARCHMASK(*bufptr) == SEARCHMASK(si->s_parms.s_ulong.value[j]))
- fprintf(fp, "%llx: %lx
", addr, *bufptr);
+ if (SEARCHMASK(*bufptr) == SEARCHMASK(si->s_parms.s_ulong.value[j])) {
+ if (si->c_num)
+ display_with_pre_and_post(bufptr, addr_base, addr, si);
+ else
+ fprintf(fp, "%llx: %lx
", addr, *bufptr);
+ }
}
}
return addr;
@@ -12048,12 +12271,17 @@ search_uint(ulong *bufptr, ulong addr, int longcnt, struct searchinfo *si)
int i, j;
int cnt = longcnt * (sizeof(long)/sizeof(int));
uint *ptr = (uint *)bufptr;
+ ulong addr_base = VIRTPAGEBASE(addr);
uint mask = si->s_parms.s_uint.mask;

for (i = 0; i < cnt; i++, ptr++, addr += sizeof(int)) {
for (j = 0; j < si->vcnt; j++) {
- if (SEARCHMASK(*ptr) == SEARCHMASK(si->s_parms.s_uint.value[j]))
- fprintf(fp, "%lx: %x
", addr, *ptr);
+ if (SEARCHMASK(*ptr) == SEARCHMASK(si->s_parms.s_uint.value[j])) {
+ if (si->c_num)
+ display_with_pre_and_post(ptr, addr_base, addr, si);
+ else
+ fprintf(fp, "%lx: %x
", addr, *ptr);
+ }
}
}
return addr;
@@ -12066,12 +12294,17 @@ search_uint_p(ulong *bufptr, ulonglong addr, int longcnt, struct searchinfo *si)
int i, j;
int cnt = longcnt * (sizeof(long)/sizeof(int));
uint *ptr = (uint *)bufptr;
+ ulonglong addr_base = PHYSPAGEBASE(addr);
uint mask = si->s_parms.s_uint.mask;

for (i = 0; i < cnt; i++, ptr++, addr += sizeof(int)) {
for (j = 0; j < si->vcnt; j++) {
- if (SEARCHMASK(*ptr) == SEARCHMASK(si->s_parms.s_uint.value[j]))
- fprintf(fp, "%llx: %x
", addr, *ptr);
+ if (SEARCHMASK(*ptr) == SEARCHMASK(si->s_parms.s_uint.value[j])) {
+ if (si->c_num)
+ display_with_pre_and_post(ptr, addr_base, addr, si);
+ else
+ fprintf(fp, "%llx: %x
", addr, *ptr);
+ }
}
}
return addr;
@@ -12083,12 +12316,17 @@ search_ushort(ulong *bufptr, ulong addr, int longcnt, struct searchinfo *si)
int i, j;
int cnt = longcnt * (sizeof(long)/sizeof(short));
ushort *ptr = (ushort *)bufptr;
+ ulong addr_base = VIRTPAGEBASE(addr);
ushort mask = si->s_parms.s_ushort.mask;

for (i = 0; i < cnt; i++, ptr++, addr += sizeof(short)) {
for (j = 0; j < si->vcnt; j++) {
- if (SEARCHMASK(*ptr) == SEARCHMASK(si->s_parms.s_ushort.value[j]))
- fprintf(fp, "%lx: %x
", addr, *ptr);
+ if (SEARCHMASK(*ptr) == SEARCHMASK(si->s_parms.s_ushort.value[j])) {
+ if (si->c_num)
+ display_with_pre_and_post(ptr, addr_base, addr, si);
+ else
+ fprintf(fp, "%lx: %x
", addr, *ptr);
+ }
}
}
return addr;
@@ -12101,12 +12339,17 @@ search_ushort_p(ulong *bufptr, ulonglong addr, int longcnt, struct searchinfo *s
int i, j;
int cnt = longcnt * (sizeof(long)/sizeof(short));
ushort *ptr = (ushort *)bufptr;
+ ulonglong addr_base = PHYSPAGEBASE(addr);
ushort mask = si->s_parms.s_ushort.mask;

for (i = 0; i < cnt; i++, ptr++, addr += sizeof(short)) {
for (j = 0; j < si->vcnt; j++) {
- if (SEARCHMASK(*ptr) == SEARCHMASK(si->s_parms.s_ushort.value[j]))
- fprintf(fp, "%llx: %x
", addr, *ptr);
+ if (SEARCHMASK(*ptr) == SEARCHMASK(si->s_parms.s_ushort.value[j])) {
+ if (si->c_num)
+ display_with_pre_and_post(ptr, addr_base, addr, si);
+ else
+ fprintf(fp, "%llx: %x
", addr, *ptr);
+ }
}
}
return addr;
--
1.7.1

--
Crash-utility mailing list
Crash-utility@redhat.com
https://www.redhat.com/mailman/listinfo/crash-utility
 
Old 02-09-2012, 07:58 PM
Dave Anderson
 
Default Add -C option for search

----- Original Message -----
> Hello Dave,
>
> I made a new patch to implement the -C option for search. This time the
> patch is accomplished in a simple manner according to your advice.
>
> Thanks.
> Zhang Yanfei
>

Hello Zhang,

Well, you've cut the patch size in half, so we're making progress... ;-)

Anyway, I find the output ugly and unmanageable. For example:

crash> search -k deadbeef -C 20
ffff810018b12a58: 4647d0 8 7fff170fb080 0 bebf80 0 0 88f8c10 507403 6264616564206b2d 3220432d20666565 30 4a3e55 88e49d0 5 ffffffff88f
07000 0 100000000 14 1
ffff810018b12af8: deadbeef 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
ffff810018b12b98: 0
crash>

Your output has a single line for the "pre" memory, and then
appends the "post" output to the targeted memory display.
Depending upon the -C argument, the line size can be absurdly
long. It should restrict the output to 80 columns, and format
the display the same way that the "rd" command does.

Secondly, to clarify things, I would prefer that the "pre"
memory and "post" memory be separate from the "target" display.

So for example, here's an output example with your patch:

crash> search -k deadbeef -C 10
ffff810032448100: 0 0 18 2b5d2cd23490 0 0 0 0 58 2b5d2cd27ac0
ffff810032448150: deadbeef 2b5d2cd293a0 2b5d2cd29700 2b5d2cd29570 2b5d2cd29470 1 1 0 20 2b5d2cd29790
ffff8100324481a0: 0
crash>

I would prefer this:

crash> search -k deadbeef -C 10
ffff810032448100: 0000000000000000 0000000000000000 ................
ffff810032448110: 0000000000000018 00002b5d2cd23490 .........4.,]+..
ffff810032448120: 0000000000000000 0000000000000000 ................
ffff810032448130: 0000000000000000 0000000000000000 ................
ffff810032448140: 0000000000000058 00002b5d2cd27ac0 X........z.,]+..
ffff810032448150: deadbeef
ffff810032448158: 00002b5d2cd293a0 00002b5d2cd29700 ...,]+.....,]+..
ffff810032448168: 00002b5d2cd29570 00002b5d2cd29470 p..,]+..p..,]+..
ffff810032448178: 0000000000000001 0000000000000001 ................
ffff810032448188: 0000000000000000 0000000000000020 ........ .......
ffff810032448198: 00002b5d2cd29790 0000000000000000 ...,]+..........
crash>

By doing that, you can signficantly simpify your new
display_with_pre_and_post() function, and get rid of
that extra get_search_page() function. All you would have
to do is determine the address, count, memory-type and
format of the "pre" and "post" sections, and pass that
information to the currently-existing display_memory()
utility function.

The display_memory() function will take care of all the
readmem() and formatting details -- there's no need
to reinvent the wheel.

Dave

--
Crash-utility mailing list
Crash-utility@redhat.com
https://www.redhat.com/mailman/listinfo/crash-utility
 
Old 02-16-2012, 05:16 AM
zhangyanfei
 
Default Add -C option for search

Hello Dave,

The new patch is attached.

I simplified the display_with_pre_and_post() function by calling the
currently-existing display_memory() function, and made the output
readable according to your advice.

Thanks
Zhang Yanfei
>From 82c67ad11d87a727fe7767b4d025f3380820ce69 Mon Sep 17 00:00:00 2001
From: zhangyanfei <zhangyanfei@cn.fujitsu.com>
Date: Thu, 16 Feb 2012 13:53:30 +0800
Subject: [PATCH] Add option -C for sub-command search.

Signed-off-by: zhangyanfei <zhangyanfei@cn.fujitsu.com>
---
help.c | 5 ++-
memory.c | 182 ++++++++++++++++++++++++++++++++++++++++++++++++++ ++++-------
2 files changed, 165 insertions(+), 22 deletions(-)

diff --git a/help.c b/help.c
index f752283..d3317f4 100755
--- a/help.c
+++ b/help.c
@@ -2343,7 +2343,7 @@ char *help_search[] = {
"seach",
"search memory",
"[-s start] [ -[kKV] | -u | -p ] [-e end | -l length] [-m mask]
"
-" -[cwh] value ...",
+" [-C num] -[cwh] value ...",
" This command searches for a given value within a range of user virtual, kernel",
" virtual, or physical memory space. If no end nor length value is entered, ",
" then the search stops at the end of user virtual, kernel virtual, or physical",
@@ -2374,6 +2374,9 @@ char *help_search[] = {
" appropriate for the memory type specified.",
" -l length Length in bytes of address range to search.",
" -m mask Ignore the bits that are set in the hexadecimal mask value.",
+" -C num Also display memory contents just before and after value. The size",
+" of the memory displayed before(after) value is num * sizeof(value).",
+" Note, this option is ignored when -c is specified.",
" -c Search for character string values instead of unsigned longs. If",
" the string contains any space(s), it must be encompassed by double",
" quotes.",
diff --git a/memory.c b/memory.c
index 55a184b..f480d32 100755
--- a/memory.c
+++ b/memory.c
@@ -87,6 +87,8 @@ struct meminfo { /* general purpose memory information structure */
struct searchinfo {
int mode;
int vcnt;
+ int c_num;
+ int memtype;
union {
/* default ulong search */
struct {
@@ -176,6 +178,7 @@ static int dump_page_lists(struct meminfo *);
static void dump_kmeminfo(void);
static int page_to_phys(ulong, physaddr_t *);
static void display_memory(ulonglong, long, ulong, int, void *);
+static void display_with_pre_and_post(void *, ulonglong, struct searchinfo *);
static ulong search_ulong(ulong *, ulong, int, struct searchinfo *);
static ulong search_uint(ulong *, ulong, int, struct searchinfo *);
static ulong search_ushort(ulong *, ulong, int, struct searchinfo *);
@@ -266,6 +269,7 @@ static ulong kmem_cache_nodelists(ulong);
#define DISPLAY_ASCII (0x2000)
#define NET_ENDIAN (0x4000)
#define DISPLAY_RAW (0x8000)
+#define NO_ERROR (0x10000)
#define DISPLAY_TYPES (DISPLAY_RAW|DISPLAY_ASCII|DISPLAY_8|
DISPLAY_16|DISPLAY_32|DISPLAY_64)

@@ -1243,13 +1247,14 @@ display_memory(ulonglong addr, long count, ulong flag, int memtype, void *opt)
char *addrtype;
struct memloc mem;
int displayed, per_line;
- int hx;
+ int hx, lost;
char hexchars[MAX_HEXCHARS_PER_LINE+1];
char ch;
int linelen;
char buf[BUFSIZE];
char slab[BUFSIZE];
int ascii_start;
+ ulong error_handle = FAULT_ON_ERROR;
char *hex_64_fmt = BITS32() ? "%.*llx " : "%.*lx ";
char *dec_64_fmt = BITS32() ? "%12lld " : "%15ld ";
char *dec_u64_fmt = BITS32() ? "%12llu " : "%20lu ";
@@ -1301,7 +1306,7 @@ display_memory(ulonglong addr, long count, ulong flag, int memtype, void *opt)
}

BZERO(&mem, sizeof(struct memloc));
- hx = linelen = typesz = per_line = ascii_start = 0;
+ hx = lost = linelen = typesz = per_line = ascii_start = 0;
location = NULL;

switch (flag & (DISPLAY_TYPES))
@@ -1350,11 +1355,17 @@ display_memory(ulonglong addr, long count, ulong flag, int memtype, void *opt)
}

for (i = a = 0; i < count; i++) {
- readmem(addr, memtype, location, typesz,
- readtype, FAULT_ON_ERROR);
+ if (flag & NO_ERROR)
+ error_handle = RETURN_ON_ERROR|QUIET;
+ if(!readmem(addr, memtype, location, typesz,
+ readtype, error_handle)) {
+ addr += typesz;
+ lost += 1;
+ continue;
+ }

- if (!(flag & DISPLAY_ASCII) && ((i % per_line) == 0)) {
- if (i) {
+ if (!(flag & DISPLAY_ASCII) && (((i - lost) % per_line) == 0)) {
+ if ((i - lost)) {
if (flag & ASCII_ENDLINE) {
fprintf(fp, " %s", hexchars);
}
@@ -1551,7 +1562,8 @@ display_memory(ulonglong addr, long count, ulong flag, int memtype, void *opt)
fprintf(fp, " %s", hexchars);
}

- fprintf(fp,"
");
+ if (lost != count )
+ fprintf(fp,"
");
}

/*
@@ -11617,7 +11629,7 @@ generic_get_kvaddr_ranges(struct vaddr_range *rp)
void
cmd_search(void)
{
- int i, c, ranges;
+ int i, c, ranges, c_num;
ulonglong start, end;
ulong mask, memtype, len;
ulong uvaddr_start, uvaddr_end;
@@ -11631,6 +11643,7 @@ cmd_search(void)

#define vaddr_overflow(ADDR) (BITS32() && ((ADDR) > 0xffffffffULL))

+ c_num = 0;
start = end = mask = sflag = pflag = Kflag = Vflag = memtype = len = 0;
kvaddr_start = kvaddr_end = 0;
uvaddr_start = UNINITIALIZED;
@@ -11668,7 +11681,7 @@ cmd_search(void)

searchinfo.mode = SEARCH_ULONG; /* default search */

- while ((c = getopt(argcnt, args, "l:ukKVps:e:v:m:hwc")) != EOF) {
+ while ((c = getopt(argcnt, args, "l:ukKVps:e:v:m:hwcC:")) != EOF) {
switch(c)
{
case 'u':
@@ -11769,6 +11782,10 @@ cmd_search(void)
searchinfo.mode = SEARCH_CHARS;
break;

+ case 'C':
+ c_num = dtoi(optarg, FAULT_ON_ERROR, NULL);
+ break;
+
default:
argerrs++;
break;
@@ -11790,6 +11807,8 @@ cmd_search(void)
if (argerrs || !sflag || !args[optind] || (len && end) || !memtype)
cmd_usage(pc->curcmd, SYNOPSIS);

+ searchinfo.memtype = memtype;
+
/*
* Verify starting address.
*/
@@ -11916,6 +11935,37 @@ cmd_search(void)
}
}

+ if (c_num) {
+ switch (searchinfo.mode)
+ {
+ case SEARCH_ULONG:
+ if (c_num > PAGESIZE()/sizeof(long)) {
+ error(INFO, "WARNING: too many numbers and"
+ " -C option is ignored
");
+ c_num = 0;
+ }
+ break;
+ case SEARCH_UINT:
+ if (c_num > PAGESIZE()/sizeof(int)) {
+ error(INFO, "WARNING: too many numbers and"
+ " -C option is ignored
");
+ c_num = 0;
+ }
+ break;
+ case SEARCH_USHORT:
+ if (c_num > PAGESIZE()/sizeof(short)) {
+ error(INFO, "WARNING: too many numbers and"
+ " -C option is ignored
");
+ c_num = 0;
+ }
+ break;
+ case SEARCH_CHARS:
+ error(INFO, "-C option ignored on string search
");
+ c_num = 0;
+ break;
+ }
+ }
+ searchinfo.c_num = c_num;

searchinfo.vcnt = 0;
while (args[optind]) {
@@ -12013,6 +12063,72 @@ cmd_search(void)

#define SEARCHMASK(X) ((X) | mask)

+static void
+display_with_pre_and_post(void *bufptr, ulonglong addr, struct searchinfo *si)
+{
+ int c_num, memtype, t, amount;
+ ulonglong addr_d;
+ ulong flag;
+ char buf[BUFSIZE];
+
+ c_num = si->c_num;
+ memtype = si->memtype;
+ flag = HEXADECIMAL|NO_ERROR|ASCII_ENDLINE;
+
+ switch (si->mode)
+ {
+ case SEARCH_USHORT:
+ t = sizeof(ushort);
+ break;
+ case SEARCH_UINT:
+ t = sizeof(uint);
+ break;
+ case SEARCH_ULONG:
+ default:
+ t = sizeof(ulong);
+ break;
+ }
+
+ switch (t)
+ {
+ case 8:
+ flag |= DISPLAY_64;
+ break;
+ case 4:
+ flag |= DISPLAY_32;
+ break;
+ case 2:
+ flag |= DISPLAY_16;
+ break;
+ }
+
+ amount = c_num * t;
+ addr_d = addr - amount < 0 ? 0 : addr - amount;
+
+ display_memory(addr_d, c_num, flag, memtype, NULL);
+
+ BZERO(buf, BUFSIZE);
+ fprintf(fp, "%s: ", mkstring(buf, VADDR_PRLEN,
+ RJUST|LONGLONG_HEX, MKSTR(&addr)));
+
+ switch(si->mode)
+ {
+ case SEARCH_ULONG:
+ fprintf(fp, "%lx
", *((ulong *)bufptr));
+ break;
+ case SEARCH_UINT:
+ fprintf(fp, "%x
", *((uint *)bufptr));
+ break;
+ case SEARCH_USHORT:
+ fprintf(fp, "%x
", *((ushort *)bufptr));
+ break;
+ }
+
+ addr_d = addr + t;
+ display_memory(addr_d, c_num, flag, memtype, NULL);
+ fprintf(fp, "
");
+}
+
static ulong
search_ulong(ulong *bufptr, ulong addr, int longcnt, struct searchinfo *si)
{
@@ -12020,8 +12136,12 @@ search_ulong(ulong *bufptr, ulong addr, int longcnt, struct searchinfo *si)
ulong mask = si->s_parms.s_ulong.mask;
for (i = 0; i < longcnt; i++, bufptr++, addr += sizeof(long)) {
for (j = 0; j < si->vcnt; j++) {
- if (SEARCHMASK(*bufptr) == SEARCHMASK(si->s_parms.s_ulong.value[j]))
- fprintf(fp, "%lx: %lx
", addr, *bufptr);
+ if (SEARCHMASK(*bufptr) == SEARCHMASK(si->s_parms.s_ulong.value[j])) {
+ if (si->c_num)
+ display_with_pre_and_post(bufptr, addr, si);
+ else
+ fprintf(fp, "%lx: %lx
", addr, *bufptr);
+ }
}
}
return addr;
@@ -12035,8 +12155,12 @@ search_ulong_p(ulong *bufptr, ulonglong addr, int longcnt, struct searchinfo *si
ulong mask = si->s_parms.s_ulong.mask;
for (i = 0; i < longcnt; i++, bufptr++, addr += sizeof(long)) {
for (j = 0; j < si->vcnt; j++) {
- if (SEARCHMASK(*bufptr) == SEARCHMASK(si->s_parms.s_ulong.value[j]))
- fprintf(fp, "%llx: %lx
", addr, *bufptr);
+ if (SEARCHMASK(*bufptr) == SEARCHMASK(si->s_parms.s_ulong.value[j])) {
+ if (si->c_num)
+ display_with_pre_and_post(bufptr, addr, si);
+ else
+ fprintf(fp, "%llx: %lx
", addr, *bufptr);
+ }
}
}
return addr;
@@ -12052,8 +12176,12 @@ search_uint(ulong *bufptr, ulong addr, int longcnt, struct searchinfo *si)

for (i = 0; i < cnt; i++, ptr++, addr += sizeof(int)) {
for (j = 0; j < si->vcnt; j++) {
- if (SEARCHMASK(*ptr) == SEARCHMASK(si->s_parms.s_uint.value[j]))
- fprintf(fp, "%lx: %x
", addr, *ptr);
+ if (SEARCHMASK(*ptr) == SEARCHMASK(si->s_parms.s_uint.value[j])) {
+ if (si->c_num)
+ display_with_pre_and_post(ptr, addr, si);
+ else
+ fprintf(fp, "%lx: %x
", addr, *ptr);
+ }
}
}
return addr;
@@ -12070,8 +12198,12 @@ search_uint_p(ulong *bufptr, ulonglong addr, int longcnt, struct searchinfo *si)

for (i = 0; i < cnt; i++, ptr++, addr += sizeof(int)) {
for (j = 0; j < si->vcnt; j++) {
- if (SEARCHMASK(*ptr) == SEARCHMASK(si->s_parms.s_uint.value[j]))
- fprintf(fp, "%llx: %x
", addr, *ptr);
+ if (SEARCHMASK(*ptr) == SEARCHMASK(si->s_parms.s_uint.value[j])) {
+ if (si->c_num)
+ display_with_pre_and_post(ptr, addr, si);
+ else
+ fprintf(fp, "%llx: %x
", addr, *ptr);
+ }
}
}
return addr;
@@ -12087,8 +12219,12 @@ search_ushort(ulong *bufptr, ulong addr, int longcnt, struct searchinfo *si)

for (i = 0; i < cnt; i++, ptr++, addr += sizeof(short)) {
for (j = 0; j < si->vcnt; j++) {
- if (SEARCHMASK(*ptr) == SEARCHMASK(si->s_parms.s_ushort.value[j]))
- fprintf(fp, "%lx: %x
", addr, *ptr);
+ if (SEARCHMASK(*ptr) == SEARCHMASK(si->s_parms.s_ushort.value[j])) {
+ if (si->c_num)
+ display_with_pre_and_post(ptr, addr, si);
+ else
+ fprintf(fp, "%lx: %x
", addr, *ptr);
+ }
}
}
return addr;
@@ -12105,8 +12241,12 @@ search_ushort_p(ulong *bufptr, ulonglong addr, int longcnt, struct searchinfo *s

for (i = 0; i < cnt; i++, ptr++, addr += sizeof(short)) {
for (j = 0; j < si->vcnt; j++) {
- if (SEARCHMASK(*ptr) == SEARCHMASK(si->s_parms.s_ushort.value[j]))
- fprintf(fp, "%llx: %x
", addr, *ptr);
+ if (SEARCHMASK(*ptr) == SEARCHMASK(si->s_parms.s_ushort.value[j])) {
+ if (si->c_num)
+ display_with_pre_and_post(ptr, addr, si);
+ else
+ fprintf(fp, "%llx: %x
", addr, *ptr);
+ }
}
}
return addr;
--
1.7.1

--
Crash-utility mailing list
Crash-utility@redhat.com
https://www.redhat.com/mailman/listinfo/crash-utility
 
Old 02-16-2012, 03:56 PM
Dave Anderson
 
Default Add -C option for search

----- Original Message -----
> Hello Dave,
>
> The new patch is attached.
>
> I simplified the display_with_pre_and_post() function by calling the
> currently-existing display_memory() function, and made the output
> readable according to your advice.
>
> Thanks
> Zhang Yanfei
>

It's looking pretty good -- a couple minor points/questions:

(1) in display_memory(), why re-initialize the error_handle each
time through the loop, instead of doing it just once?
(2) in display_memory(), shouldn't the "lost" variable be reset
to 0 after a line of output is printed?

Dave

--
Crash-utility mailing list
Crash-utility@redhat.com
https://www.redhat.com/mailman/listinfo/crash-utility
 
Old 02-16-2012, 04:10 PM
Dave Anderson
 
Default Add -C option for search

----- Original Message -----
>
>
> ----- Original Message -----
> > Hello Dave,
> >
> > The new patch is attached.
> >
> > I simplified the display_with_pre_and_post() function by calling the
> > currently-existing display_memory() function, and made the output
> > readable according to your advice.
> >
> > Thanks
> > Zhang Yanfei
> >
>
> It's looking pretty good -- a couple minor points/questions:
>
> (1) in display_memory(), why re-initialize the error_handle each
> time through the loop, instead of doing it just once?
> (2) in display_memory(), shouldn't the "lost" variable be reset
> to 0 after a line of output is printed?

Hello Zhang,

Never mind (2) -- my misunderstanding, it still needs to be reflected
in the cumulative total.

That being said:

(1) I'll just move the error_handle initialization up above the loop
(2) To avoid confusion with "-c", I think I'll change the option
letter to "-x" (for context") and rewrite the help description
slightly.

Other than that, consider it queued for crash-6.0.4.

Thanks,
Dave

--
Crash-utility mailing list
Crash-utility@redhat.com
https://www.redhat.com/mailman/listinfo/crash-utility
 

Thread Tools




All times are GMT. The time now is 07:21 AM.

VBulletin, Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO ©2007, Crawlability, Inc.
Copyright 2007 - 2008, www.linux-archive.org