Bug 834260
| Summary: | struct command should accept option -o even with address specified | ||
|---|---|---|---|
| Product: | Red Hat Enterprise Linux 6 | Reporter: | Stanislav Kozina <skozina> |
| Component: | crash | Assignee: | Dave Anderson <anderson> |
| Status: | CLOSED ERRATA | QA Contact: | Guangze Bai <gbai> |
| Severity: | medium | Docs Contact: | |
| Priority: | medium | ||
| Version: | 6.2 | CC: | mhomolov, qcai, yshao |
| Target Milestone: | rc | ||
| Target Release: | --- | ||
| Hardware: | x86_64 | ||
| OS: | Unspecified | ||
| Whiteboard: | |||
| Fixed In Version: | crash-6.0.9-1.el6 | Doc Type: | Bug Fix |
| Doc Text: | Story Points: | --- | |
| Clone Of: | Environment: | ||
| Last Closed: | 2013-02-21 08:34:08 UTC | Type: | Bug |
| Regression: | --- | Mount Type: | --- |
| Documentation: | --- | CRM: | |
| Verified Versions: | Category: | --- | |
| oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |
| Cloudforms Team: | --- | Target Upstream Version: | |
| Embargoed: | |||
> Expected results:
>
> crash> struct net_device 0xffff880312458020 | head -n 5
Ah, here the command would obviously look like:
crash> struct -o net_device 0xffff880312458020 | head -n 5
Sorry about the typo;-/
When used with an address, the struct command passes the heavy lifting off to the embedded gdb module, and the output is straight from gdb. When used with -o, it has gdb print the structure declaration behind the scenes, and then walks through the output, doing an ugly parsing operation trying to pick out strucure members, and as it finds them, queries gdb for the member's offset, and then pushes it out before the member name. And it's not always fully-functional, as it sometimes it "misses" some members. Doing the same for the output of a particular structure with data would be even uglier. But with persistance it I suppose it could be done, although I'm not particularly excited about doing it. What would be interesting to consider as an alternative, would be to have "struct -o address" basically do what it does now, but instead of printing the structure.member offset, push out the member's virtual address -- but without the contents of the structure. That would be relatively easy to implement. (In reply to comment #2) > When used with an address, the struct command passes the heavy lifting > off to the embedded gdb module, and the output is straight from gdb. > > When used with -o, it has gdb print the structure declaration behind the > scenes, and then walks through the output, doing an ugly parsing operation > trying to pick out strucure members, and as it finds them, queries gdb > for the member's offset, and then pushes it out before the member name. > And it's not always fully-functional, as it sometimes it "misses" some > members. > > Doing the same for the output of a particular structure with data would > be even uglier. But with persistance it I suppose it could be done, > although I'm not particularly excited about doing it. Thank you for the explanation of implementation, I was not aware there is such a difference between processing w/o the address. > What would be interesting to consider as an alternative, would be to > have "struct -o address" basically do what it does now, but instead of > printing the structure.member offset, push out the member's virtual > address -- but without the contents of the structure. That would be > relatively easy to implement. This might be actually good compromise - it's definitely better than current behavior, and it would give me what am I searching for. > This might be actually good compromise - it's definitely better than
> current behavior, and it would give me what am I searching for.
Cool -- I like the idea as well. I'll look into it...
Pretty straight-forward fit -- taking a thread_info struct as an
example, here's the current functionality:
crash> thread_info ffff81002a796000
struct thread_info {
task = 0xffff81003ed767e0,
exec_domain = 0xffffffff802f78e0,
flags = 128,
status = 1,
cpu = 5,
preempt_count = 0,
addr_limit = {
seg = 18446604435732824064
},
restart_block = {
fn = 0xffffffff80095a52 <do_no_restart_syscall>,
arg0 = 0,
arg1 = 0,
arg2 = 0,
arg3 = 0
}
}
crash> thread_info -o
struct thread_info {
[0] struct task_struct *task;
[8] struct exec_domain *exec_domain;
[16] __u32 flags;
[20] __u32 status;
[24] __u32 cpu;
[28] int preempt_count;
[32] mm_segment_t addr_limit;
[40] struct restart_block restart_block;
}
SIZE: 80
crash> thread_info -ox
struct thread_info {
[0x0] struct task_struct *task;
[0x8] struct exec_domain *exec_domain;
[0x10] __u32 flags;
[0x14] __u32 status;
[0x18] __u32 cpu;
[0x1c] int preempt_count;
[0x20] mm_segment_t addr_limit;
[0x28] struct restart_block restart_block;
}
SIZE: 0x50
crash>
And the new functionality looks like:
crash> thread_info -o ffff81002a796000
struct thread_info {
[ffff81002a796000] struct task_struct *task;
[ffff81002a796008] struct exec_domain *exec_domain;
[ffff81002a796010] __u32 flags;
[ffff81002a796014] __u32 status;
[ffff81002a796018] __u32 cpu;
[ffff81002a79601c] int preempt_count;
[ffff81002a796020] mm_segment_t addr_limit;
[ffff81002a796028] struct restart_block restart_block;
}
SIZE: 80
crash>
Nice, thank you very much!
> And the new functionality looks like:
>
> crash> thread_info -o ffff81002a796000
> struct thread_info {
> [ffff81002a796000] struct task_struct *task;
> [ffff81002a796008] struct exec_domain *exec_domain;
> [ffff81002a796010] __u32 flags;
> [ffff81002a796014] __u32 status;
> [ffff81002a796018] __u32 cpu;
> [ffff81002a79601c] int preempt_count;
> [ffff81002a796020] mm_segment_t addr_limit;
> [ffff81002a796028] struct restart_block restart_block;
> }
> SIZE: 80
> crash>
(In reply to comment #6) > Nice, thank you very much! > > > And the new functionality looks like: > > > > crash> thread_info -o ffff81002a796000 > > struct thread_info { > > [ffff81002a796000] struct task_struct *task; > > [ffff81002a796008] struct exec_domain *exec_domain; > > [ffff81002a796010] __u32 flags; > > [ffff81002a796014] __u32 status; > > [ffff81002a796018] __u32 cpu; > > [ffff81002a79601c] int preempt_count; > > [ffff81002a796020] mm_segment_t addr_limit; > > [ffff81002a796028] struct restart_block restart_block; > > } > > SIZE: 80 > > crash> All right -- I'll re-work the help page, and queue it up for crash-6.0.8. Eventually it will arrive in RHEL6 presuming I can get crash onto the RHEL6.4 approved components list. Since the problem described in this bug report should be resolved in a recent advisory, it has been closed with a resolution of ERRATA. For information on the advisory, and where to find the updated files, follow the link below. If the solution does not work for you, open a new bug report. http://rhn.redhat.com/errata/RHBA-2013-0317.html |
Description of problem: When printing structure, it would be beneficial to get address of each field in the structure directly without manual adding the address + offset. Version-Release number of selected component (if applicable): # rpm -qf `which crash` crash-5.1.8-1.el6.x86_64 megatron$ rpm -qf `which crash` crash-6.0.5-0.x86_64 How reproducible: Always. Steps to Reproduce: 1. net | grep eth0 2. struct -o net_device ffff880312458020 | head -n 5 3. Actual results: crash> struct -o net_device ffff880312458020 | head -n 5 struct: -o option not valid with an address argument struct: -o option not valid with an address argument struct net_device { name = "eth0\000\000\000\000\000\000\000\000\000\000\000", name_hlist = { next = 0x0, Expected results: crash> struct net_device 0xffff880312458020 | head -n 5 struct net_device { [0xffff880312458020] name = "eth0\000\000\000\000\000\000\000\000\000\000\000", [0xffff880312458030] name_hlist = { [0xffff880312458030] next = 0x0, [0xffff880312458038] pprev = 0xffff880317be6890 Additional info: This would be pretty handy when it's neccessary to follow links in the structures.