[操作疑難] 請教android-x86 mesa (找到原因但唔識救)

本帖最後由 ati16800 於 2018-1-14 23:49 編輯

整左個android-x86 marshmallow,但係vmware上面行唔到一個超簡單自己寫既unity3d apk (不過係真機就行到),出signal 11 (SIGSEGV),想嘗試解決,唔知有無C兄熟mesa可以請教?

現階段只係知死位係gallium_dri.so (pc:005c1191, mesa/main/texcompress_etc.c),call stack既底係由libunity.so call teximage() (mesa/main/teximage.c)。

直接死因找到了,但唔識點改。具體的code請看#5樓貼。

請各位C兄指點,萬分感謝!

無 source code 好難知咩事
不過出 SIGSEGV 會唔會係個 Unity Material 有 texture parameter 係 null ?
正常係 Win / Mac / iOS / Android 如果 null texture 只會出 warning
試過係 PS vita 都係會 crash, 結果要 check 晒所有 material 既 texture 唔會有 null

TOP

本帖最後由 ati16800 於 2018-1-14 13:34 編輯
無 source code 好難知咩事


成套android-x86都有source code,我都係由source code build出來既。bug應該就係mesa call vm driver 之間出現,如果只係d低級錯誤就會好易改。
不過唔好叫我係每一個function前面都加句debug log (雖然已經加左d),因為數量實在太多了。

TOP

(我) 無 (你) source code 好難知咩事

咁可唔可以 dump 個 call stack 睇睇 ?

TOP

本帖最後由 ati16800 於 2018-1-14 23:59 編輯

static void st_UnmapTextureImage(struct gl_context *ctx,  struct gl_texture_image *texImage,       GLuint slice)
{
   struct st_context *st = st_context(ctx);
   struct st_texture_image *stImage  = st_texture_image(texImage);

   if (st_etc_fallback(st, texImage)) {
      /* Decompress the ETC texture to the mapped one. */
      unsigned z = slice + stImage->base.Face;
      struct st_texture_image_transfer *itransfer = &stImage->transfer[z];
      struct pipe_transfer *transfer = itransfer->transfer;
      assert(z == transfer->box.z);
      if (transfer->usage & PIPE_TRANSFER_WRITE) {
         if (texImage->TexFormat == MESA_FORMAT_ETC1_RGB8) {
                     ........
         }
         else {       
        if (itransfer!=NULL) {
            _mesa_unpack_etc2_format(itransfer->map, transfer->stride,
                                     itransfer->temp_data,  <-------這裡的temp_data=0 ??
                                     itransfer->temp_stride,  
                                     transfer->box.width, transfer->box.height,
                                     texImage->TexFormat);
              }
         }
      }
      itransfer->temp_data = NULL;
      itransfer->temp_stride = 0;
      itransfer->map = 0;
   }
   st_texture_image_unmap(st, stImage, slice);
}

static void
etc2_unpack_rgb8(uint8_t *dst_row,
                 unsigned dst_stride,
                 const uint8_t *src_row,   <-------這裡的src_row 來自temp_data=0
                 unsigned src_stride,
                 unsigned width,
                 unsigned height)
{
   const unsigned bw = 4, bh = 4, bs = 8, comps = 4;
   struct etc2_block block;
   unsigned x, y, i, j;

   for (y = 0; y < height; y += bh) {
      const uint8_t *src = src_row;  <-------這裡的src 來自src_row=0
      /*
       * Destination texture may not be a multiple of four texels in
       * height. Compute a safe height to avoid writing outside the texture.
       */
      const unsigned h = MIN2(bh, height - y);

      for (x = 0; x < width; x+= bw) {
         /*
          * Destination texture may not be a multiple of four texels in
          * width. Compute a safe width to avoid writing outside the texture.
          */
         const unsigned w = MIN2(bw, width - x);
           
         etc2_rgb8_parse_block(&block, src,     <-------這裡的src = 0
                               false /* punchthrough_alpha */);

         for (j = 0; j < h; j++) {
            uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps;
            for (i = 0; i < w; i++) {
               etc2_rgb8_fetch_texel(&block, i, j, dst,
                                     false /* punchthrough_alpha */);
               dst[3] = 255;
               dst += comps;
            }
         }
         src += bs;
      }
      src_row += src_stride;
   }
}

static void
etc2_rgb8_parse_block(struct etc2_block *block,
                      const uint8_t *src,
                      GLboolean punchthrough_alpha)
{  
   unsigned i;
   GLboolean diffbit = false;
   static const int lookup[8] = { 0, 1, 2, 3, -4, -3, -2, -1 };

   const int R_plus_dR = (src[0] >> 3) + lookup[src[0] & 0x7];   <-------這裡的src=0, 0[0]即死。

TOP

temp_data 來自 st_cb_texture.c
null 既可能係 etc_data = null
又或者 st_FreeTextureImageBuffer(), st_UnmapTextureImage() call 左兩次
如果你有 source 可以 check 下 etc_data 係唔係 null,
如果係 null 試下直接 return
不過無個 run 到既 project 只睇 source code 有D難 debug






static void
st_MapTextureImage(struct gl_context *ctx,
                   struct gl_texture_image *texImage,
                   GLuint slice, GLuint x, GLuint y, GLuint w, GLuint h,
                   GLbitfield mode,
                   GLubyte **mapOut, GLint *rowStrideOut)
{
   struct st_context *st = st_context(ctx);
   struct st_texture_image *stImage = st_texture_image(texImage);
   unsigned pipeMode;
   GLubyte *map;
   struct pipe_transfer *transfer;

   pipeMode = 0x0;
   if (mode & GL_MAP_READ_BIT)
      pipeMode |= PIPE_TRANSFER_READ;
   if (mode & GL_MAP_WRITE_BIT)
      pipeMode |= PIPE_TRANSFER_WRITE;
   if (mode & GL_MAP_INVALIDATE_RANGE_BIT)
      pipeMode |= PIPE_TRANSFER_DISCARD_RANGE;

   map = st_texture_image_map(st, stImage, pipeMode, x, y, slice, w, h, 1,
                              &transfer);
   if (map) {
      if (st_etc_fallback(st, texImage)) {
         /* ETC isn't supported by all gallium drivers, where it's represented
          * by uncompressed formats. We store the compressed data (as it's
          * needed for image copies in OES_copy_image), and decompress as
          * necessary in Unmap.
          *
          * Note: all ETC1/ETC2 formats have 4x4 block sizes.
          */
         unsigned z = transfer->box.z;
         struct st_texture_image_transfer *itransfer = &stImage->transfer[z];

         unsigned bytes = _mesa_get_format_bytes(texImage->TexFormat);
         unsigned stride = *rowStrideOut = itransfer->temp_stride =
            _mesa_format_row_stride(texImage->TexFormat, texImage->Width2);
         *mapOut = itransfer->temp_data =
            stImage->etc_data + ((x / 4) * bytes + (y / 4) * stride) +
            z * stride * texImage->Height2 / 4;
         itransfer->map = map;
      }
      else {
         /* supported mapping */
         *mapOut = map;
         *rowStrideOut = transfer->stride;
      }
   }
   else {
      *mapOut = NULL;
      *rowStrideOut = 0;
   }
}

TOP

如果係 Unity o個邊 call 左 unmap 兩次, 再可以 check null 再 return
如果係 Mesa o個邊既 bug, 就要跟下先知, 同埋可以 report 返俾 Mesa 問下點 fix

TOP

今日build個userdebug版,竟然無死,不過都係出唔到unity3d個splash screen.

TOP