[Crash-utility] [PATCH 3/3] arm/arm64: read elf notes for qemu generated cores

Dave Anderson anderson at redhat.com
Thu Nov 19 17:08:06 UTC 2015



----- Original Message -----
> On Thu, Nov 19, 2015 at 11:50:22AM -0500, Dave Anderson wrote:
> > 
> > 
> > ----- Original Message -----
> > > QEMU can generate both non-makedumpfile (just elf) and makedumpfile
> > > formatted kdumps. In neither case will crash_notes have prstatus, as
> > > crash_kexec doesn't run in the kernel, however the elf notes will
> > > contain the prstatus, and we can dig them out of there.
> > 
> > Hi Andrew,
> > 
> > Refresh my memory -- without the patch, what does "bt" do when run
> > against the active tasks from QEMU generated dumps?
> 
> On initial loading a couple warnings are output
> 
>   WARNING: invalid note (n_type != NT_PRSTATUS)
>   WARNING: cannot retrieve registers for active tasks
> 
> When attempting 'bt', crash segfaults
> 
>   PID: 2424   TASK: ffffffc057a46e00  CPU: 1   COMMAND: "bash"
>   bt: WARNING: cannot determine starting stack frame for task
>   ffffffc057a46e00
>   Segmentation fault

Wow, it's worse than I thought!  Thanks for addressing it.

So anyway, I'll just wait for you to post an updated v2 patch set.

Thanks,
  Dave
  

> 
> Thanks,
> drew
> 
> > 
> > Dave
> > 
> > 
> > > ---
> > >  arm.c     | 22 ++++++++++++++++++++++
> > >  arm64.c   | 22 ++++++++++++++++++++++
> > >  defs.h    |  1 +
> > >  netdump.c | 21 +++++++++++++++++++++
> > >  4 files changed, 66 insertions(+)
> > > 
> > > diff --git a/arm.c b/arm.c
> > > index ffc7c06d0f42c..8fc3d48a8ac89 100644
> > > --- a/arm.c
> > > +++ b/arm.c
> > > @@ -597,6 +597,28 @@ arm_get_crash_notes(void)
> > >  		note = (Elf32_Nhdr *)buf;
> > >  		p = buf + sizeof(Elf32_Nhdr);
> > >  
> > > +		/*
> > > +		 * dumpfiles created with qemu won't have crash_notes, but there will
> > > +		 * be elf notes.
> > > +		 */
> > > +		if (note->n_namesz == 0 && (DISKDUMP_DUMPFILE() || KDUMP_DUMPFILE()))
> > > {
> > > +			if (DISKDUMP_DUMPFILE())
> > > +				note = diskdump_get_prstatus_percpu(i);
> > > +			else if (KDUMP_DUMPFILE())
> > > +				note = netdump_get_prstatus_percpu(i);
> > > +			if (note) {
> > > +				/*
> > > +				 * SIZE(note_buf) accounts for a "final note", which is a
> > > +				 * trailing empty elf note header.
> > > +				 */
> > > +				long notesz = SIZE(note_buf) - sizeof(Elf32_Nhdr);
> > > +
> > > +				if (sizeof(Elf32_Nhdr) + roundup(note->n_namesz, 4) +
> > > +				    note->n_descsz == notesz)
> > > +					BCOPY((char *)note, buf, notesz);
> > > +			}
> > > +		}
> > > +
> > >  		if (note->n_type != NT_PRSTATUS) {
> > >  			error(WARNING, "invalid note (n_type != NT_PRSTATUS)\n");
> > >  			goto fail;
> > > diff --git a/arm64.c b/arm64.c
> > > index 6187b96d25a4d..91b35787e6942 100644
> > > --- a/arm64.c
> > > +++ b/arm64.c
> > > @@ -1827,6 +1827,28 @@ arm64_get_crash_notes(void)
> > >  		note = (Elf64_Nhdr *)buf;
> > >  		p = buf + sizeof(Elf64_Nhdr);
> > >  
> > > +		/*
> > > +		 * dumpfiles created with qemu won't have crash_notes, but there will
> > > +		 * be elf notes.
> > > +		 */
> > > +		if (note->n_namesz == 0 && (DISKDUMP_DUMPFILE() || KDUMP_DUMPFILE()))
> > > {
> > > +			if (DISKDUMP_DUMPFILE())
> > > +				note = diskdump_get_prstatus_percpu(i);
> > > +			else if (KDUMP_DUMPFILE())
> > > +				note = netdump_get_prstatus_percpu(i);
> > > +			if (note) {
> > > +				/*
> > > +				 * SIZE(note_buf) accounts for a "final note", which is a
> > > +				 * trailing empty elf note header.
> > > +				 */
> > > +				long notesz = SIZE(note_buf) - sizeof(Elf64_Nhdr);
> > > +
> > > +				if (sizeof(Elf64_Nhdr) + roundup(note->n_namesz, 4) +
> > > +				    note->n_descsz == notesz)
> > > +					BCOPY((char *)note, buf, notesz);
> > > +			}
> > > +		}
> > > +
> > >  		if (note->n_type != NT_PRSTATUS) {
> > >  			error(WARNING, "invalid note (n_type != NT_PRSTATUS)\n");
> > >  			goto fail;
> > > diff --git a/defs.h b/defs.h
> > > index 1bcd1b3b177db..981b030cc6688 100644
> > > --- a/defs.h
> > > +++ b/defs.h
> > > @@ -5722,6 +5722,7 @@ void dump_registers_for_qemu_mem_dump(void);
> > >  void kdump_backup_region_init(void);
> > >  void display_regs_from_elf_notes(int, FILE *);
> > >  void display_ELF_note(int, int, void *, FILE *);
> > > +void *netdump_get_prstatus_percpu(int);
> > >  #define PRSTATUS_NOTE (1)
> > >  #define QEMU_NOTE     (2)
> > >  
> > > diff --git a/netdump.c b/netdump.c
> > > index bfa818fdef8e1..3ff49f0577c23 100644
> > > --- a/netdump.c
> > > +++ b/netdump.c
> > > @@ -2345,6 +2345,27 @@ dump_Elf64_Nhdr(Elf64_Off offset, int store)
> > >  	return len;
> > >  }
> > >  
> > > +void *
> > > +netdump_get_prstatus_percpu(int cpu)
> > > +{
> > > +	int online;
> > > +
> > > +	if ((cpu < 0) || (cpu >= nd->num_prstatus_notes))
> > > +		return NULL;
> > > +
> > > +	/*
> > > +	 * If no cpu mapping was done, then there must be
> > > +	 * a one-to-one relationship between the number
> > > +	 * of online cpus and the number of notes.
> > > +	 */
> > > +	if ((online = get_cpus_online()) &&
> > > +	    (online == kt->cpus) &&
> > > +	    (online != nd->num_prstatus_notes))
> > > +		return NULL;
> > > +
> > > +	return nd->nt_prstatus_percpu[cpu];
> > > +}
> > > +
> > >  /*
> > >   *  Send the request to the proper architecture hander.
> > >   */
> > > --
> > > 2.4.3
> > > 
> > > 
> 




More information about the Crash-utility mailing list