Hello Wouter, thanks for this additional information. I could reproduce the issue with a usb webcam inside a buster amd64 VM. Unfortunately this camera button was with the german translation not visible with the small resolution of that VM.
It took a little time to get into the smalltalk side of things. But I think I have found a problem - on the c side of the plugins. (gdb) bt #0 0x00007fffafa33c82 in convertImageRGB24toARGB32 (cam=0x7fffafa37180 <camInfo>) at ./unix/plugins/CameraPlugin/sqCamera-linux.c:333 #1 0x00007fffafa33f2a in convertImage (cam=0x7fffafa37180 <camInfo>) at ./unix/plugins/CameraPlugin/sqCamera-linux.c:412 #2 0x00007fffafa34d10 in CameraGetFrame (camNum=1, buf=0x7fffb2b9fcb4 "", pixelCount=76800) at ./unix/plugins/CameraPlugin/sqCamera-linux.c:836 #3 0x00007fffafa3352c in primGetFrame () at ./unix/src/plugins/CameraPlugin/CameraPlugin.c:160 #4 0x0000555555578ca4 in dispatchFunctionPointer (aFunctionPointer=0x7fffafa33461 <primGetFrame>) at ./build-tree/gnu-interp.c:3809 #5 0x00005555555769f8 in callExternalPrimitive (functionID=0x7fffafa33461 <primGetFrame>) at ./build-tree/gnu-interp.c:2512 #6 0x000055555558fc92 in primitiveExternalCall () at ./build-tree/gnu-interp.c:17732 #7 0x0000555555578ca4 in dispatchFunctionPointer (aFunctionPointer=0x55555558faf0 <primitiveExternalCall>) at ./build-tree/gnu-interp.c:3809 #8 0x000055555558227a in interpret () at ./build-tree/gnu-interp.c:9339 #9 0x00005555555a7cef in main (argc=8, argv=0x7fffffffe2a8, envp=0x7fffffffe2f0) at ./unix/vm/sqUnixMain.c:1458 (gdb) list convertImageRGB24toARGB32 319 static void 320 convertImageRGB24toARGB32 (camPtr cam) 321 { 322 unsigned char *src = cam->inBuffer; 323 unsigned long int *dst = cam->sqBuffer; <-- sizeof(*dst) == 8, should be 4 ? 324 unsigned long int pixelCount = cam->sqPixels; 325 unsigned long int pixel; 326 int i; 327 328 if (0 == dst) return; 329 330 for ( i = 0; i < pixelCount; i++) { 331 pixel = 0xFF000000 | (*src++ << 16); 332 pixel = pixel | (*src++ << 8); 333 *dst++ = pixel | *src++; 334 } 335 } Here the buffer allocated in the squeak-vm is given to primGetFrame and gets finally the image written to in convertImageRGB24toARGB32. Unfortunately these conversion functions use "unsigned long int *dst", with a long int having a size of 8 bytes at amd64, while we got just 4 bytes per pixel reserved from squeak-vm, therefore overrunning our reserved buffer. When just installing the packages the plugin so.CameraPlugin gets used from the package squeak-plugins-scratch. But a similar so.CameraPlugin is already packaged with squeak-vm. squeak-vm: /usr/lib/squeak/4.10.2.2614/so.CameraPlugin squeak-plugins-scratch: /usr/lib/scratch/plugins/so.CameraPlugin So this probably should be clarified if the plugins are really needed in both packages. Therefore this report should be changed to packages squeak-vm and squeak-plugins-scratch? Attached both patches change this buffer element size in the conversion function from 8 to 4. With them applied both plugins were able to show me the picture from the webcam inside scratch. Kind regards, Bernhard
Description: Make camera plugin work at amd64 platform. The convertImageRGB* using a "unsigned long int" pointer. Unfortunately is sizeof(unsigned long int) at amd64 8 bytes. Therefore the buffer allocated at smalltalk-side and given to c-side to receive the picture is being overrun. Author: Bernhard Ãbelacker <bernha...@mailbox.org> Bug-Debian: https://bugs.debian.org/892016 Forwarded: no Last-Update: 2018-08-05 --- squeak-plugins-scratch-1.4.0.2~svn.r83.orig/camera/sqCamera-linux.c +++ squeak-plugins-scratch-1.4.0.2~svn.r83/camera/sqCamera-linux.c @@ -320,11 +320,14 @@ static void convertImageRGB24toARGB32 (camPtr cam) { unsigned char *src = cam->inBuffer; - unsigned long int *dst = cam->sqBuffer; + unsigned int *dst = cam->sqBuffer; unsigned long int pixelCount = cam->sqPixels; unsigned long int pixel; int i; + if (sizeof(*dst) != 4) + printf("Invalid buffer element size, expect crash: %i should be %i\n", sizeof(*dst), 4); + if (0 == dst) return; for ( i = 0; i < pixelCount; i++) { @@ -339,11 +342,14 @@ static void convertImageRGB444toARGB32 (camPtr cam) { unsigned char *src = cam->inBuffer; - unsigned long int *dst = cam->sqBuffer; + unsigned int *dst = cam->sqBuffer; unsigned long int pixelCount = cam->sqPixels; unsigned long int r,g,b,pixel; int i; + if (sizeof(*dst) != 4) + printf("Invalid buffer element size, expect crash: %i should be %i\n", sizeof(*dst), 4); + if (0 == dst) return; /* Byte0: (g)ggg(b)bbb, Byte1: xxxx(r)rrr */ @@ -365,11 +371,14 @@ static void convertImageRGB565toARGB32 (camPtr cam) { unsigned char *src = cam->inBuffer; - unsigned long int *dst = cam->sqBuffer; + unsigned int *dst = cam->sqBuffer; unsigned long int pixelCount = cam->sqPixels; unsigned long int r,g,b,pixel; int i; + if (sizeof(*dst) != 4) + printf("Invalid buffer element size, expect crash: %i should be %i\n", sizeof(*dst), 4); + if (0 == dst) return; /* Byte0: ggg(r)rrrr, Byte1: (b)bbbb(g)gg */
Description: Make camera plugin work at amd64 platform. The convertImageRGB* using a "unsigned long int" pointer. Unfortunately is sizeof(unsigned long int) at amd64 8 bytes. Therefore the buffer allocated at smalltalk-side and given to c-side to receive the picture is being overrun. Author: Bernhard Ãbelacker <bernha...@mailbox.org> Bug-Debian: https://bugs.debian.org/892016 Forwarded: no Last-Update: 2018-08-05 --- squeak-vm-4.10.2.2614.orig/unix/plugins/CameraPlugin/sqCamera-linux.c +++ squeak-vm-4.10.2.2614/unix/plugins/CameraPlugin/sqCamera-linux.c @@ -320,11 +320,14 @@ static void convertImageRGB24toARGB32 (camPtr cam) { unsigned char *src = cam->inBuffer; - unsigned long int *dst = cam->sqBuffer; + unsigned int *dst = cam->sqBuffer; unsigned long int pixelCount = cam->sqPixels; unsigned long int pixel; int i; + if (sizeof(*dst) != 4) + printf("Invalid buffer element size, expect crash: %i should be %i\n", sizeof(*dst), 4); + if (0 == dst) return; for ( i = 0; i < pixelCount; i++) { @@ -339,11 +342,14 @@ static void convertImageRGB444toARGB32 (camPtr cam) { unsigned char *src = cam->inBuffer; - unsigned long int *dst = cam->sqBuffer; + unsigned int *dst = cam->sqBuffer; unsigned long int pixelCount = cam->sqPixels; unsigned long int r,g,b,pixel; int i; + if (sizeof(*dst) != 4) + printf("Invalid buffer element size, expect crash: %i should be %i\n", sizeof(*dst), 4); + if (0 == dst) return; /* Byte0: (g)ggg(b)bbb, Byte1: xxxx(r)rrr */ @@ -365,11 +371,14 @@ static void convertImageRGB565toARGB32 (camPtr cam) { unsigned char *src = cam->inBuffer; - unsigned long int *dst = cam->sqBuffer; + unsigned int *dst = cam->sqBuffer; unsigned long int pixelCount = cam->sqPixels; unsigned long int r,g,b,pixel; int i; + if (sizeof(*dst) != 4) + printf("Invalid buffer element size, expect crash: %i should be %i\n", sizeof(*dst), 4); + if (0 == dst) return; /* Byte0: ggg(r)rrrr, Byte1: (b)bbbb(g)gg */
apt update apt install xserver-xorg lightdm openbox pulseaudio xterm psmisc htop mc tmux strace dpkg-dev devscripts quilt gdb systemd-coredump dh-buildinfo libcairo2-dev libpango1.0-dev libglib2.0-dev libv4l-dev cdbs cmake libasound2-dev libdbus-1-dev libffi-dev libgl1-mesa-dev libjpeg-dev libpulse-dev libspeex-dev libvorbis-dev libxt-dev libxtst-dev sharutils apt install scratch squeak-vm-dbgsym squeak-plugins-scratch-dbg export DISPLAY=:0 export LANG=C $ scratch Executing: /usr/lib/squeak/4.10.2.2614/squeakvm -encoding UTF-8 -vm-display-x11 -plugins /usr/lib/scratch/plugins/:/usr/lib/squeak/4.10.2.2614/ -vm-sound-pulse /usr/share/scratch/Scratch.image Segmentation fault 11552520 BitBlt>setDestForm: 11552428 BitBlt class>toForm: 11552180 WarpBlt class>toForm: 11552088 ScratchCameraDialog>step 11551972 Morph>stepAt: 11549332 [] in PasteUpMorph>runStepMethods 11548836 OrderedCollection>do: 11549056 [] in PasteUpMorph>runStepMethods 11548168 BlockContext>ifError: 11548076 PasteUpMorph>runStepMethods 11540344 PasteUpMorph>doOneCycleNow 11538548 PasteUpMorph>doOneCycle 4967012 [] in Project>spawnNewProcess 4967104 [] in BlockContext>newProcess Aborted (core dumped) $ gdb -q --args /usr/lib/squeak/4.10.2.2614/squeakvm -encoding UTF-8 -vm-display-x11 -plugins /usr/lib/scratch/plugins/:/usr/lib/squeak/4.10.2.2614/ -vm-sound-pulse /usr/share/scratch/Scratch.image Reading symbols from /usr/lib/squeak/4.10.2.2614/squeakvm...Reading symbols from /usr/lib/debug/.build-id/15/573e8b23d0b91c0f2420d3035865f37122a0ad.debug...done. done. (gdb) run Starting program: /usr/lib/squeak/4.10.2.2614/squeakvm -encoding UTF-8 -vm-display-x11 -plugins /usr/lib/scratch/plugins/:/usr/lib/squeak/4.10.2.2614/ -vm-sound-pulse /usr/share/scratch/Scratch.image [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". [New Thread 0x7ffff2f80700 (LWP 1199)] [New Thread 0x7ffff277f700 (LWP 1200)] Thread 1 "squeakvm" received signal SIGSEGV, Segmentation fault. 0x00005555555854e0 in lookupMethodInClass (class=<optimized out>) at ./build-tree/gnu-interp.c:13387 13387 ./build-tree/gnu-interp.c: No such file or directory. (gdb) bt #0 0x00005555555854e0 in lookupMethodInClass (class=<optimized out>) at ./build-tree/gnu-interp.c:13387 #1 0x000055555558b462 in interpret () at ./build-tree/gnu-interp.c:9287 #2 0x000055555557519b in main (argc=<optimized out>, argv=0x7fffffffe518, envp=<optimized out>) at ./unix/vm/sqUnixMain.c:1458 dpkg --purge --force-depends squeak-vm squeak-vm-dbgsym squeak-plugins-scratch DEB_BUILD_OPTIONS="debug nostrip noopt" dpkg-buildpackage -uc -us -b dpkg -i squeak-vm_4.10.2.2614-6_amd64.deb $ gdb -q --args /usr/lib/squeak/4.10.2.2614/squeakvm -encoding UTF-8 -vm-display-x11 -plugins /usr/lib/scratch/plugins/:/usr/lib/squeak/4.10.2.2614/ -vm-sound-pulse /usr/share/scratch/Scratch.image directory /home/benutzer/squeak-vm/try1/squeak-vm-4.10.2.2614 set height 0 set width 0 set pagination off b CameraGetFrame - cp /usr/share/scratch /home/benutzer/scratch-image -a - LANG=C /usr/lib/squeak/4.10.2.2614/squeakvm -encoding UTF-8 -vm-display-x11 -plugins /usr/lib/scratch/plugins/:/usr/lib/squeak/4.10.2.2614/ -vm-sound-pulse /home/benutzer/scratch-image/Scratch.image - hold shift pressed and click on the R from SCRATCH in the top left corner - "turn fill screen off" - click in the appearing left white area - "open..." - "browser" - Select "Scratch-UI-Dialogs" in the first column - Select "ScratchCameraDialog" in the second column - Select "stepping" in the third column - Select "step" in the fourth column - Select in the field below all except the first line and cut by alt+x - Save with alt+s - Enter your name and alt+s - Select "button ops" in the third column - Select "close" in the fourth column - Select in the field below all except the first line and paste by alt+v - Add new line " self halt." after " frameForm ifNil: [↑ self]." - Save with alt+s The step method looks like timer based called and therefore triggers on every call a "breakpoint". Therefore moved the content of step into close and place the "breakpoint" "self halt." there. - "Costumes" - "Camera" - Button "Done" - "Halt encountered" dialog opens - click Button "Debug" - Finally a new debug window opens. - click int he left white area - "save" (to have not to repeat every step on a new debugging attempt) - some error messages appear about saving, but on the next attempt we start exactly here. - (Stepping is done by alt+t) - alt+t leave first self halt. - alt+t leave second self halt. t2 ← CameraPlugin getFrameForCamera: 1 into: frameForm bits. #### (selected/highlighted) - alt+t (step) t2 ← CameraPlugin getFrameForCamera: 1 into: frameForm bits. ######################################### (selected/highlighted) - alt+e (send/step into) t2 > 0 ###### (selected/highlighted) - instecting variable t2 shows "1" - alt+e - inspecting variables crashes now the whole vm. (gdb) bt #0 0x00007fffafa33c82 in convertImageRGB24toARGB32 (cam=0x7fffafa37180 <camInfo>) at ./unix/plugins/CameraPlugin/sqCamera-linux.c:333 #1 0x00007fffafa33f2a in convertImage (cam=0x7fffafa37180 <camInfo>) at ./unix/plugins/CameraPlugin/sqCamera-linux.c:412 #2 0x00007fffafa34d10 in CameraGetFrame (camNum=1, buf=0x7fffb2b9fcb4 "", pixelCount=76800) at ./unix/plugins/CameraPlugin/sqCamera-linux.c:836 #3 0x00007fffafa3352c in primGetFrame () at ./unix/src/plugins/CameraPlugin/CameraPlugin.c:160 #4 0x0000555555578ca4 in dispatchFunctionPointer (aFunctionPointer=0x7fffafa33461 <primGetFrame>) at ./build-tree/gnu-interp.c:3809 #5 0x00005555555769f8 in callExternalPrimitive (functionID=0x7fffafa33461 <primGetFrame>) at ./build-tree/gnu-interp.c:2512 #6 0x000055555558fc92 in primitiveExternalCall () at ./build-tree/gnu-interp.c:17732 #7 0x0000555555578ca4 in dispatchFunctionPointer (aFunctionPointer=0x55555558faf0 <primitiveExternalCall>) at ./build-tree/gnu-interp.c:3809 #8 0x000055555558227a in interpret () at ./build-tree/gnu-interp.c:9339 #9 0x00005555555a7cef in main (argc=8, argv=0x7fffffffe2a8, envp=0x7fffffffe2f0) at ./unix/vm/sqUnixMain.c:1458 (gdb) list convertImageRGB24toARGB32 319 static void 320 convertImageRGB24toARGB32 (camPtr cam) 321 { 322 unsigned char *src = cam->inBuffer; 323 unsigned long int *dst = cam->sqBuffer; 324 unsigned long int pixelCount = cam->sqPixels; 325 unsigned long int pixel; 326 int i; 327 328 if (0 == dst) return; 329 330 for ( i = 0; i < pixelCount; i++) { 331 pixel = 0xFF000000 | (*src++ << 16); 332 pixel = pixel | (*src++ << 8); 333 *dst++ = pixel | *src++; 334 } 335 } - Why is there so.CameraPlugin in squeak-vm and squeak-plugins-scratch? squeak-vm: /usr/lib/squeak/4.10.2.2614/so.CameraPlugin squeak-plugins-scratch: /usr/lib/scratch/plugins/so.CameraPlugin - Debug information for /usr/lib/squeak/4.10.2.2614/so.CameraPlugin and most other plugins seems not included in squeak-vm-dbgsym - Building with DEB_BUILD_OPTIONS="debug nostrip noopt" gives a plugin that misses some "inline" functions, that work with optimzed builds. Should that be regular "static" functions?