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?

Reply via email to