I meet a ghost bug, this almost kills me…
The source code is as simple as the following:
struct fbusb_par { struct usb_interface *interface; u32 palette[PSEUDO_PALETTE_SIZE]; }; static int fbusb_probe(struct usb_interface *interface, const struct usb_device_id *id) { struct fb_info *info; info = framebuffer_alloc(sizeof(struct fbusb_par), &interface->dev); if (!info) return -ENOMEM; par = info->par; par->interface = interface; return 0; } static void fbusb_disconnect(struct usb_interface *interface) { dev_info(&interface->dev, "framebuffer device now disconnected.\n"); } static const struct usb_device_id fbusb_ids[] = { { USB_DEVICE(0x04b4, 0x1004) }, { } }; MODULE_DEVICE_TABLE(usb, fbusb_ids); static struct usb_driver fbusb_driver = { .name = "fbusb", .probe = fbusb_probe, .disconnect = fbusb_disconnect, .id_table = fbusb_ids, }; module_usb_driver(fbusb_driver);
The mysterious bug is this driver crashed at par->interface = interface; and after debug, par is a null pointer, but info is not a null pointer! Let’s check framebuffer_alloc source code, if return info is correct, there is no way par to be null pointer.
struct fb_info *framebuffer_alloc(size_t size, struct device *dev) { #define BYTES_PER_LONG (BITS_PER_LONG/8) #define PADDING (BYTES_PER_LONG - (sizeof(struct fb_info) % BYTES_PER_LONG)) int fb_info_size = sizeof(struct fb_info); struct fb_info *info; char *p; if (size) fb_info_size += PADDING; p = kzalloc(fb_info_size + size, GFP_KERNEL); if (!p) return NULL; info = (struct fb_info *) p; if (size) info->par = p + fb_info_size; info->device = dev; #ifdef CONFIG_FB_BACKLIGHT mutex_init(&info->bl_curve_mutex); #endif return info; #undef PADDING #undef BYTES_PER_LONG } EXPORT_SYMBOL(framebuffer_alloc);
Also step into this framebuffer_alloc function, in this function info->par is not null and its value is correct. So what is happening once info returned? who changed info->par to null? This is really weird bug…I have never seen such thing before.
PS: I guess I find the problem. If I put the source into Linux source code, it will report some .ko is missing, but if I move it to package/kernel as a package, it will happen that weird problem. So it is package missing problem.