rnmapbox / maps

A Mapbox react native module for creating custom maps
MIT License
2.26k stars 846 forks source link

[Bug]: Crash on Android with dynamic shape source (Ios works fine), Fatal signal 11 (SIGSEGV), code 2 (SEGV_ACCERR) #3385

Open stalteri opened 8 months ago

stalteri commented 8 months ago

Mapbox Implementation

Mapbox

Mapbox Version

default

Platform

Android

@rnmapbox/maps version

10.1.13

Standalone component to reproduce

import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { Navigator, routes, MainStack } from 'app/navigation';
import { Feature, Geometry, Point, LineString, GeoJsonProperties, Position } from 'geojson';
import { LineLayer, ShapeSource, MapView, PointAnnotation } from '@rnmapbox/maps';

const styles = StyleSheet.create({
    waypoint: {
    width: 24,
    height: 24,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: 'white',
    borderRadius: 50,
  },
});

type Waypoint = {
  index: number;
  coordinates: Position;
  height: number;
};

const BugReportExample = () => {
  const [lineString, setLineString] = React.useState<LineString>({ type: 'LineString', coordinates: [] });
  const [points, setPoints] = React.useState<Waypoint[]>([]);
  const [cycled, setCycled] = React.useState<boolean>(false);

  const feature = React.useMemo<Feature<LineString>>(() => {
    return {
      type: 'Feature',
      properties: {
        id: 'clgnqq4xc00v4bpxv7hs9m5kt',
        name: 'FeatureLines',
      },
      geometry: lineString,
    };
  }, [lineString]);

  const updateLineString = React.useCallback((coordinates: Position) => {
    setLineString(prev => ({
      ...prev,
      coordinates: prev?.coordinates?.concat([coordinates]),
    } as LineString));
  }, []);

  const handlePress = React.useCallback((feature: Feature<Geometry, GeoJsonProperties>) => {
    if (feature.geometry.type === 'Point' && !cycled) {
      const point: Point = feature.geometry;

      setPoints(prev => [...prev, {
        index: prev.length,
        coordinates: point.coordinates,
        height: 0,
      }]);

      updateLineString(point.coordinates);
    }
  }, [cycled, updateLineString]);

  const handleDragEnd = React.useCallback((coordinates: Position, index: number) => {
    setPoints(prev => {
      const newPoints = prev;
      newPoints.splice(index, 1, { ...prev[index], coordinates });

      return newPoints;
    });

    setLineString(prev => {
      const newCoordinates = prev.coordinates;
      newCoordinates.splice(index, 1, coordinates);

      return {
        ...prev,
        coordinates: newCoordinates,
      };
    });
  }, []);

  const handleDrag = React.useCallback((coordinates: Position, index: number) => {
      setLineString(prev => {
      const newCoordinates = prev.coordinates;
      newCoordinates.splice(index, 1, coordinates);

      return {
        ...prev,
        coordinates: newCoordinates,
      };
    });
  }, []);

  const handleWaypointPress = React.useCallback((point: Waypoint, index: number) => {
    if (index === 0 && !cycled) {
      updateLineString(point.coordinates);
      setCycled(true);
    }
  }, [cycled, updateLineString]);

  return (
    <MapView
      style={{ flex: 1 }}
      onPress={handlePress}
      logoEnabled={false}
      scaleBarEnabled={false}
      styleURL='mapbox://styles/mapbox-map-design/ckhqrf2tz0dt119ny6azh975y'
    >
      {points.map((item, index) => (
        <PointAnnotation
          draggable
          id={String(index)}
          key={String(index)}
          coordinate={item.coordinates}
          onSelected={() => handleWaypointPress(item, index)}
          onDragEnd={feature => handleDragEnd(feature.geometry.coordinates, index)}
          onDrag={feature => handleDrag(feature.geometry.coordinates, index)}
        >
          <View style={styles.waypoint}>
            {typeof index === 'number' && <Text>{index + 1}</Text>}
          </View>
        </PointAnnotation>
      ))}

      <ShapeSource
        id='source'
        shape={feature}
        buffer={512}
        tolerance={0.5}
      >
        <LineLayer
          id='lines'
          layerIndex={11}
          sourceID='source'
          style={{
            lineWidth: 3,
            lineColor: 'white',
          }}
        />
      </ShapeSource>
    </MapView>
  );
};

export default BugReportExample;

Observed behavior and steps to reproduce

random crash on map with ShapeSource and also no lines were rendered https://github.com/rnmapbox/maps/assets/48121568/3b3018fb-c91a-4679-894a-754892db668f

on ios works fine with no crashes and also lines renders image

Expected behavior

no crash and render the LineSource just like on ios

Notes / preliminary analysis

Fatal signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 0x725f6adb60 in tid 20891 (Worker 2), pid 20767 (com.nexops) 2024-02-20 13:41:35.114 20972-20972 DEBUG pid-20972 A Cmdline: com.nexops 2024-02-20 13:41:35.114 20972-20972 DEBUG pid-20972 A pid: 20767, tid: 20891, name: Worker 2 >>> com.nexops <<< 2024-02-20 13:41:35.115 20972-20972 DEBUG pid-20972 A #01 pc 00000000000eab24 /data/app/~~YUXzRXUVSEG_6Cvdl5Plqw==/com.nexops-0viZPywZ0VQYABftACdfCg==/lib/arm64/libc++_shared.so (BuildId: a59088f9640cd272bc9542d94dc84a0c88afd558) 2024-02-20 13:41:35.115 20972-20972 DEBUG pid-20972 A #02 pc 00000000000ea818 /data/app/~~YUXzRXUVSEG_6Cvdl5Plqw==/com.nexops-0viZPywZ0VQYABftACdfCg==/lib/arm64/libc++_shared.so (BuildId: a59088f9640cd272bc9542d94dc84a0c88afd558) 2024-02-20 13:41:35.115 20972-20972 DEBUG pid-20972 A #03 pc 00000000000e6e30 /data/app/~~YUXzRXUVSEG_6Cvdl5Plqw==/com.nexops-0viZPywZ0VQYABftACdfCg==/lib/arm64/libc++_shared.so (BuildId: a59088f9640cd272bc9542d94dc84a0c88afd558) 2024-02-20 13:41:35.115 20972-20972 DEBUG pid-20972 A #04 pc 00000000000e6cc0 /data/app/~~YUXzRXUVSEG_6Cvdl5Plqw==/com.nexops-0viZPywZ0VQYABftACdfCg==/lib/arm64/libc++_shared.so (gxx_personality_v0+224) (BuildId: a59088f9640cd272bc9542d94dc84a0c88afd558) 2024-02-20 13:41:35.115 20972-20972 DEBUG pid-20972 A #05 pc 0000000000143d4c /data/app/~~YUXzRXUVSEG_6Cvdl5Plqw==/com.nexops-0viZPywZ0VQYABftACdfCg==/lib/arm64/libmapbox-common.so (BuildId: b956b55bbfa93def) 2024-02-20 13:41:35.115 20972-20972 DEBUG pid-20972 A #06 pc 0000000000144254 /data/app/~~YUXzRXUVSEG_6Cvdl5Plqw==/com.nexops-0viZPywZ0VQYABftACdfCg==/lib/arm64/libmapbox-common.so (BuildId: b956b55bbfa93def) 2024-02-20 13:41:35.115 20972-20972 DEBUG pid-20972 A #07 pc 000000000018f6dc /data/app/~~YUXzRXUVSEG_6Cvdl5Plqw==/com.nexops-0viZPywZ0VQYABftACdfCg==/lib/arm64/libmapbox-common.so (BuildId: b956b55bbfa93def) 2024-02-20 13:41:35.115 20972-20972 DEBUG pid-20972 A #08 pc 0000000000192454 /data/app/~~YUXzRXUVSEG_6Cvdl5Plqw==/com.nexops-0viZPywZ0VQYABftACdfCg==/lib/arm64/libmapbox-common.so (mapbox::common::geojson::convert(mapbox::feature::value const&)+420) (BuildId: b956b55bbfa93def) 2024-02-20 13:41:35.115 20972-20972 DEBUG pid-20972 A #09 pc 00000000002c5368 /data/app/~~YUXzRXUVSEG_6Cvdl5Plqw==/com.nexops-0viZPywZ0VQYABftACdfCg==/lib/arm64/libmapbox-maps.so (BuildId: 886096c02edc2c34) 2024-02-20 13:41:35.115 20972-20972 DEBUG pid-20972 A #10 pc 000000000045c698 /data/app/~~YUXzRXUVSEG_6Cvdl5Plqw==/com.nexops-0viZPywZ0VQYABftACdfCg==/lib/arm64/libmapbox-maps.so (BuildId: 886096c02edc2c34) 2024-02-20 13:41:35.115 20972-20972 DEBUG pid-20972 A #11 pc 000000000045c448 /data/app/~~YUXzRXUVSEG_6Cvdl5Plqw==/com.nexops-0viZPywZ0VQYABftACdfCg==/lib/arm64/libmapbox-maps.so (BuildId: 886096c02edc2c34) 2024-02-20 13:41:35.115 20972-20972 DEBUG pid-20972 A #12 pc 00000000001aa3a8 /data/app/~~YUXzRXUVSEG_6Cvdl5Plqw==/com.nexops-0viZPywZ0VQYABftACdfCg==/lib/arm64/libmapbox-common.so (mapbox::common::platform::processTask(std::ndk1::function<void ()> const&)+32) (BuildId: b956b55bbfa93def) 2024-02-20 13:41:35.115 20972-20972 DEBUG pid-20972 A #13 pc 000000000019b7c0 /data/app/~~YUXzRXUVSEG_6Cvdl5Plqw==/com.nexops-0viZPywZ0VQYABftACdfCg==/lib/arm64/libmapbox-common.so (BuildId: b956b55bbfa93def)

Additional links and references

maybe problem with this?

08 pc 0000000000192454 /data/app/~~YUXzRXUVSEG_6Cvdl5Plqw==/com.nexops-0viZPywZ0VQYABftACdfCg==/lib/arm64/libmapbox-common.so (mapbox::common::geojson::convert(mapbox::feature::value const&)+420) (BuildId: b956b55bbfa93def)

mfazekas commented 8 months ago

Thanks for the report, I wasn't able to reproduce the issue in our env. What is your RN version?

image

stalteri commented 8 months ago

Thanks for response.

What is your RN version?

0.73.4 Android 13

mfazekas commented 8 months ago

@stalteri I see our app uses 0.73.4 as well. Can you try to reproduce in our example app, or a new app created with npx react-native init?

stalteri commented 8 months ago

@stalteri I see our app uses 0.73.4 as well. Can you try to reproduce in our example app, or a new app created with npx react-native init?

Ok, I'll try to reproduce asap.

stalteri commented 8 months ago

@mfazekas

@stalteri I see our app uses 0.73.4 as well. Can you try to reproduce in our example app, or a new app created with npx react-native init?

https://github.com/rnmapbox/maps/assets/48121568/f88581f4-4885-4f29-9f5d-7db622054c80

P.S. I forget to add a "draggable" prop to PointAnnotation in the component to reproduce (alredy edited).

VovkViktor commented 8 months ago

I crashed too when I used ShapeSource with prop shape type 'LineString'. RN 0.73.5, "@rnmapbox/maps": "^10.1.18" and "@rnmapbox/maps": "^10.1.19"

 <MapboxGL.MapView
              ref={refMap}
              style={{flex: 1, width: '100%'}}
              styleURL={MapboxGL.StyleURL.Street}>
              <MapboxGL.ShapeSource
                id="lineSource"
                buffer={32}
                shape={{
                  type: 'LineString',
                  coordinates: locations,
                }}>
                <MapboxGL.LineLayer
                  id="lineLayer"
                  sourceID="lineSource"
                  style={{lineColor: 'blue', lineWidth: 3}}
                />
              </MapboxGL.ShapeSource>
              <MapboxGL.UserLocation
                visible={true}
                animated={true}
                androidRenderMode="gps"
              />
              <MapboxGL.Camera
                ref={cameraRef}
                allowUpdates={true}
                followUserLocation={true}
                animationMode="moveTo"
                animationDuration={200}
                followZoomLevel={16}
                defaultSettings={{
                  zoomLevel: 16,
                }}
              />
            </MapboxGL.MapView>

Also I created a new empty project on RN and installed only MapBox package. It isn't work too image image

VovkViktor commented 8 months ago

I noticed that it happens if "coordinates" prop array length less than 2

stalteri commented 7 months ago

I noticed that it happens if "coordinates" prop array length less than 2

You are right, there no crash if I render ShapeSource only if coordinates length > 1

wrldh commented 6 months ago

Just had the same issue with version 10.1.21 and the reason is exact the same as described above (only one Position in ShapeSource's coordinates).

namphamdev commented 4 months ago

Wondering why there's no error message, the app just crashes without any useful message

mfazekas commented 4 months ago

It's likely an NDK incompatibility issue. Mapbox 10.* uses NDK 21 and it's known to be incompatible with NDK23. More specifically any C++ exception thrown inside Mapbox 10 causes a crash.

Mapbox 11 is NDK 23 and it seems to be compatible with newer NDK 23 and newer.

RN 0.71, 0.72 used NDK 23 RN 0.73 used NDK 25 RN 0.74, 0.75 uses NDK 26

See https://github.com/mapbox/mapbox-maps-android/issues/1697 https://github.com/mapbox/mapbox-maps-android/issues/1697#issuecomment-1582593957