[Crash-utility] Re: [PATCH v1 1/3] ppc64: Fix bt printing error stack trace

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 24/09/24 09:10, Tao Liu wrote:
Hi Aditya & Lianbo,

Thanks for your review on this ppc fix. Recently I'm working on
another high priority task, so I may not respond to your comments in
time, sorry for that.

On Tue, Sep 24, 2024 at 2:28 AM Aditya Gupta <adityag@xxxxxxxxxxxxx> wrote:
<...snip...>
How about this approach ?

I feel this might be more dependable, as the file command also uses
this, as well as fadump (PowerPC firmware-assisted dump) in the kernel.

As a sidenote, there is still some issue either in patch #1 or #3
causing all secondary CPUs (where swapper task is running) to show all
threads as '_end'
What do you think ?
Yes, I like the idea of extracting the abi version through vmlinux.
Thanks a lot for your approach and code, but I haven't tried your code
yet. I will test it when my current task finishes.

Sure, take your time :)


Thanks Tao,

Aditya Gupta





Thanks,
Tao Liu
Either way what you chose, I do realise the idea to utilise the
'std r2, STK_GOT(r1)' in such a way, was interesting and smart.

     static bool
     is_ppc64_elf_abi_v2(void)
     {
         const char *kernel_file = pc->namelist;
         int fd, swap;
         char eheader[BUFSIZE];
         Elf64_Ehdr *elf64;

         if ((fd = open(kernel_file, O_RDONLY)) < 0) {
                 error(INFO, "%s: %s\n", kernel_file, strerror(errno));
                 return FALSE;
         }
         if (read(fd, eheader, BUFSIZE) != BUFSIZE) {
             error(INFO, "%s: %s\n", kernel_file, strerror(errno));
                 close(fd);
                 return FALSE;
         }
         close(fd);

         if (!STRNEQ(eheader, ELFMAG) || eheader[EI_VERSION] != EV_CURRENT)
                 return FALSE;

         elf64 = (Elf64_Ehdr *)&eheader[0];

         swap = (((eheader[EI_DATA] == ELFDATA2LSB) &&
              (__BYTE_ORDER == __BIG_ENDIAN)) ||
             ((eheader[EI_DATA] == ELFDATA2MSB) &&
              (__BYTE_ORDER == __LITTLE_ENDIAN)));

         /*
          * The ABI version is stored in E_FLAGS in the ELF header, atleast for
          * ppc64 binaries.
          *
          * These logic is also used by the 'file' command, which states this in
          * its magic file:
          *
          *     >18      leshort         20              PowerPC or cisco 4500,
          *     >18      leshort         21              64-bit PowerPC or cisco 7500,
          *     >>48     lelong          0               Unspecified or Power ELF V1 ABI,
          *     >>48     lelong          1               Power ELF V1 ABI,
          *     >>48     lelong          2               OpenPOWER ELF V2 ABI,
          *
          * The '>18' above means, data at 18 (0x12), which is basically
          * 'elf64->e_machine', which will be 20 for PPC, and 21 for PPC64
          *
          * Similarly, '>>48' is offset 48 (0x30) in the file, which is
          * basically 'elf64->e_flags', which has the ELF ABI version
          */
         if (elf64->e_flags == 2) {
                 /* ABI v2 */
                 return TRUE;
         } else if (elf64->e_flags == 1) {
                 /* ABI v1 */
                 return FALSE;
         }

         error(WARNING, "Unstable elf_abi v1/v2 detection.\n");
         return FALSE;
     }

Also, we can those values in the ELF header:

     $ hexdump vmlinux-little-endian
     0000000 457f 464c 0102 0001 0000 0000 0000 0000
     0000010 0002 0015 (= 21 = E_MACHINE)  0001 0000 0000 0000 0000 c000
     0000020 0040 0000 0000 0000 8bf8 0040 0000 0000
     0000030 0002 (= E_FLAGS = ABI)   0000 0040 0038 0002 0040 0027 0026
     0000040 0001 0000 0007 0000 0000 0001 0000 0000

Also, I see 'pc->namelist' is basically the kernel filename, is that
correct ? Can that be renamed to kernel_filename or something ?

Thanks,
Aditya Gupta

Thanks,

Aditya Gupta

+   char buf1[BUFSIZE];
+   char *pos1, *pos2;
+   int errflag = 0;
+   ulong stk_got = 0;
+   static bool ret = false;
+   static bool checked = false;
+
+   if (checked == true || !symbol_exists("tm_reclaim"))
+           return ret;
+
+   sprintf(buf1, "x/16i tm_reclaim");
+   open_tmpfile();
+   if (!gdb_pass_through(buf1, pc->tmpfile, GNU_RETURN_ON_ERROR))
+           goto out;
+   checked = true;
+   rewind(pc->tmpfile);
+   while (fgets(buf1, BUFSIZE, pc->tmpfile)) {
+           // "std r2, STK_GOT(r1)" is expected
+           if (strstr(buf1, "std") &&
+               strstr(buf1, "(r1)") &&
+               (pos1 = strstr(buf1, "r2,"))) {
+                   pos1 += strlen("r2,");
+                   for (pos2 = pos1; *pos2 != '\0' && *pos2 != '('; pos2++);
+                   *pos2 = '\0';
+                   stk_got = stol(pos1, RETURN_ON_ERROR|QUIET, &errflag);
+                   break;
+           }
+   }
+
+   if (!errflag) {
+           switch (stk_got) {
+           case 24:
+                   ret = true;
+           case 40:
+                   goto out;
+           }
+   }
+   error(WARNING, "Unstable elf_abi v1/v2 detection.\n");
+out:
+   close_tmpfile();
+   return ret;
+}
   /*
    *  get the SP and PC values for idle tasks.
@@ -2834,9 +2880,17 @@ get_ppc64_frame(struct bt_info *bt, ulong *getpc, ulong *getsp)
     sp = ppc64_get_sp(task);
     if (!INSTACK(sp, bt))
             goto out;
-   readmem(sp+STACK_FRAME_OVERHEAD, KVADDR, &regs,
-           sizeof(struct ppc64_pt_regs),
-           "PPC64 pt_regs", FAULT_ON_ERROR);
+
+   if (THIS_KERNEL_VERSION >= LINUX(6,2,0) && is_ppc64_elf_abi_v2()) {
+           readmem(sp+STACK_SWITCH_FRAME_REGS, KVADDR, &regs,
+                   sizeof(struct ppc64_pt_regs),
+                   "PPC64 pt_regs", FAULT_ON_ERROR);
+   } else {
+           readmem(sp+STACK_FRAME_OVERHEAD, KVADDR, &regs,
+                   sizeof(struct ppc64_pt_regs),
+                   "PPC64 pt_regs", FAULT_ON_ERROR);
+   }
+
     ip = regs.nip;
     closest = closest_symbol(ip);
     if (STREQ(closest, ".__switch_to") || STREQ(closest, "__switch_to")) {
--
Crash-utility mailing list -- devel@xxxxxxxxxxxxxxxxxxxxxxxxxxx
To unsubscribe send an email to devel-leave@xxxxxxxxxxxxxxxxxxxxxxxxxxx
https://${domain_name}/admin/lists/devel.lists.crash-utility.osci.io/
Contribution Guidelines: https://github.com/crash-utility/crash/wiki




[Index of Archives]     [Fedora Development]     [Fedora Desktop]     [Fedora SELinux]     [Yosemite News]     [KDE Users]     [Fedora Tools]

 

Powered by Linux