Causas y soluciones de la señal 11 (SIGSEGV), código 2 (SEGV_ACCERR)

Las palabras clave no son fáciles, indique la fuente para la reimpresión
https://blog.csdn.net/newchenxf/article/details/121537539


1 Conclusión

Tal vez abriste este artículo tarde en la noche cuando estabas trabajando horas extras. Realmente no tienes mucho tiempo y realmente quieres irte a casa, así que no puedo empezar con un montón de tonterías. Esta vez, hagamos una conclusión primero como referencia, si es inútil, date prisa y encuentra otra...

Aparece SIGSEGV, sí 进程执行了一个无效的内存引用. Actualmente estoy experimentando dos bloqueos por diferentes motivos, que se enumeran aquí.

razón:

  1. 对象在使用时已被释放。
  2. 对象没有初始化。

Para ampliar un poco más:

  1. 对象A用局部变量初始化,分配在栈上,函数结束就提前释放了。赋值给其他对象B,B在其他函数引用A时,出现崩溃。
  2. 对象没有被初始化,判空又不为空,使用时崩溃。

Solución:

  1. 使用智能指针,或者A改成全局变量。
  2. 保证变量在使用前初始化,例如在构造函数初始化。

Ok, a continuación, hablemos de ello en detalle.

2 casos en que un objeto ha sido liberado mientras estaba en uso

2.1 Antecedentes del problema

Después de escribir el código C++ de Android, se bloquea cuando se ejecuta y el registro es el siguiente:

11-25 15:07:25.546 24467 24527 E glesdemo: ReadMissingBones, m_BoneInfoMap address 0x7e70ed0f88, size 52


11-25 15:07:25.554 24467 24527 E glesdemo: GetBoneIDMap, m_BoneInfoMap size 0


11-25 15:07:25.654 24718 24718 I crash_dump64: performing dump of process 24467 (target tid = 24527)
11-25 15:07:25.655 24718 24718 F DEBUG   : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
11-25 15:07:25.655 24718 24718 F DEBUG   : Build fingerprint: 'Xiaomi/sagit/sagit:8.0.0/OPR1.170623.027/V10.2.1.0.OCACNFK:user/release-keys'
11-25 15:07:25.655 24718 24718 F DEBUG   : Revision: '0'
11-25 15:07:25.655 24718 24718 F DEBUG   : ABI: 'arm64'
11-25 15:07:25.655 24718 24718 F DEBUG   : pid: 24467, tid: 24527, name: GLThread 6769  >>> com.chenxf.opengles <<<
11-25 15:07:25.655 24718 24718 F DEBUG   : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x23d70a00000020
11-25 15:07:25.655 24718 24718 F DEBUG   :     x0   3c23d70a00000020  x1   0000007e70ed0ce0  x2   0000000000000018  x3   3c23d70a00000020
11-25 15:07:25.655 24718 24718 F DEBUG   :     x4   0000007e72355438  x5   0000007e70ed0f68  x6   0000007e70ed11a0  x7   0000000000000000
11-25 15:07:25.655 24718 24718 F DEBUG   :     x8   0000007e72355420  x9   3c23d70a00000020  x10  0000007e70ed0e98  x11  0000007e70ed11a0
11-25 15:07:25.655 24718 24718 F DEBUG   :     x12  0000007e71a44808  x13  0000000000000001  x14  ffffffffffffffff  x15  26204f3d44495400
11-25 15:07:25.656 24718 24718 F DEBUG   :     x16  0000007e72bbbac0  x17  0000007e72b828bc  x18  0000000000000001  x19  0000007e7efa5400
11-25 15:07:25.656 24718 24718 F DEBUG   :     x20  0000007e72b70ee4  x21  000000001384f730  x22  000000001384b8f0  x23  0000007e8f90ab47
11-25 15:07:25.656 24718 24718 F DEBUG   :     x24  0000000000000008  x25  0000007e7efa5498  x26  0000000000000000  x27  0000000000000000
11-25 15:07:25.656 24718 24718 F DEBUG   :     x28  0000000000000002  x29  0000007e70ed0c80  x30  0000007e72b79bfc
11-25 15:07:25.656 24718 24718 F DEBUG   :     sp   0000007e70ed0c70  pc   0000007e72b79bfc  pstate 0000000020000000
11-25 15:07:25.661 24718 24718 F DEBUG   :
11-25 15:07:25.661 24718 24718 F DEBUG   : backtrace:
11-25 15:07:25.661 24718 24718 F DEBUG   :     #00 pc 0000000000028bfc  /data/app/com.chenxf.opengles-bU4sOnN8Yuev-eQs6nf7QA==/base.apk (offset 0x1606000)
11-25 15:07:25.661 24718 24718 F DEBUG   :     #01 pc 0000000000031780  /data/app/com.chenxf.opengles-bU4sOnN8Yuev-eQs6nf7QA==/base.apk (offset 0x1606000)
11-25 15:07:25.661 24718 24718 F DEBUG   :     #02 pc 000000000003e1ec  /data/app/com.chenxf.opengles-bU4sOnN8Yuev-eQs6nf7QA==/base.apk (offset 0x1606000)
11-25 15:07:25.661 24718 24718 F DEBUG   :     #03 pc 000000000003e1b8  /data/app/com.chenxf.opengles-bU4sOnN8Yuev-eQs6nf7QA==/base.apk (offset 0x1606000)
11-25 15:07:25.661 24718 24718 F DEBUG   :     #04 pc 000000000003e16c  /data/app/com.chenxf.opengles-bU4sOnN8Yuev-eQs6nf7QA==/base.apk (offset 0x1606000)
11-25 15:07:25.661 24718 24718 F DEBUG   :     #05 pc 000000000003e110  /data/app/com.chenxf.opengles-bU4sOnN8Yuev-eQs6nf7QA==/base.apk (offset 0x1606000)

No hay información de pila de eso en absoluto. No sé qué línea en absoluto, ¿cuál podría ser la razón de esto?

Primero enumero el código dependiente de la siguiente manera:
El animador de primera clase:

class Animator
{
    
    
public:
	Animator(Animation* animation)
	{
    
    
		m_CurrentAnimation = animation;
	}

	void CalculateBoneTransform()
	{
    
    
		//省略代码...
		std::map<std::string,BoneInfo> boneInfoMap = m_CurrentAnimation->GetBoneIDMap();
		DEBUG_LOGCATE();

		if (boneInfoMap.find(nodeName) != boneInfoMap.end())
		{
    
    
			DEBUG_LOGCATE();
			//省略代码...
		}
	}

private:
	Animation* m_CurrentAnimation;

};

La animación de segunda clase

class Animation
{
    
    
public:
	Animation() = default;

	Animation(const std::string& animationPath, ModelAnim* model)
	{
    
    
		m_BoneInfoMap = model.GetBoneInfoMap();//getting m_BoneInfoMap from Model class
		LOGCATE("ReadMissingBones, m_BoneInfoMap address %p, size %d", &m_BoneInfoMap,m_BoneInfoMap.size());
	}

	~Animation()
	{
    
    
	}

	inline const std::map<std::string,BoneInfo>& GetBoneIDMap() 
	{
    
    
		LOGCATE("GetBoneIDMap, m_BoneInfoMap size %d", m_BoneInfoMap.size());
		return m_BoneInfoMap;
	}

private:
	std::map<std::string, BoneInfo> m_BoneInfoMap;
};

La tercera clase inicializa las 2 clases anteriores y usa:

void Model3DAnimSample::Init() {
    
    
	Animation animation(path + "/model/vampire/dancing_vampire.dae", m_pModel);
    m_pAnimator = new Animator(&animation);
    //...
}

void Model3DAnimSample::Draw(int screenW, int screenH) {
    
    
	m_pAnimator->CalculateBoneTransform();
	//省略...
}

2.2 Análisis de causas

Puedo reproducir localmente, así que agregué muchos registros para rastrear, vea las dos primeras líneas del registro superior:

11-25 15:07:25.546 24467 24527 E glesdemo: ReadMissingBones, m_BoneInfoMap address 0x7e70ed0f88, size 52
11-25 15:07:25.554 24467 24527 E glesdemo: GetBoneIDMap, m_BoneInfoMap size 0

Este m_BoneInfoMap tiene 52 cuando se le asigna un valor. Cuando lo llama la función CalculateBoneTransform de Animator, lee el valor y se convierte en 0. Si se usa más, fallará.

¿por qué? ¡Después de leer durante mucho tiempo, m_BoneInfoMap no se ha modificado en ningún otro lugar! ! !

Veamos de nuevo la información de la pila:
11-25 15:07:25.655 24718 24718 F DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x23d70a00000020

¿Qué significan estos 2 caracteres?
SIGSEGV: El proceso ejecutó una referencia de memoria no válida.
SEGV_MAPERR: Indica un error de mapa de pila.

Entonces salió la razón:
在Init函数,animation是局部变量,栈上分配的,再赋值给m_pAnimator。 Init函数结束后,animation就无效了,后面m_pAnimator再使用animation,就是栈上的脏数据,所以出现了SIGSEGV

2.3 Soluciones

  1. Haz de Animation una variable global de la clase. Ahora mismo
 	m_pAnimation = new Animation(path + "/model/vampire/dancing_vampire.dae", m_pModel);
    m_pAnimator = new Animator(m_pAnimation);
  1. Use punteros inteligentes para crear animaciones, a saber, share_ptr. Para punteros inteligentes, consulte: https://blog.csdn.net/newchenxf/article/details/116019535

3 Caso 2 El objeto no se inicializa

3.1 Antecedentes del problema

Misma pila que el Caso 1

12-27 16:06:13.513 20962 20962 F DEBUG   : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
12-27 16:06:13.513 20962 20962 F DEBUG   : Build fingerprint: 'Xiaomi/sagit/sagit:8.0.0/OPR1.170623.027/V10.2.1.0.OCACNFK:user/release-keys'
12-27 16:06:13.513 20962 20962 F DEBUG   : Revision: '0'
12-27 16:06:13.513 20962 20962 F DEBUG   : ABI: 'arm64'
12-27 16:06:13.513 20962 20962 F DEBUG   : pid: 20871, tid: 20905, name: GLThread 7653  >>> com.chenxf.opengles <<<
12-27 16:06:13.513 20962 20962 F DEBUG   : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x72006500640069
12-27 16:06:13.513 20962 20962 F DEBUG   :     x0   0072006500640069  x1   0000000000000302  x2   00000000ffffffff  x3   0000007196a37e0c
12-27 16:06:13.513 20962 20962 F DEBUG   :     x4   003d3d3d3d3d204a  x5   0000008000000080  x6   26415e3d44495400  x7   0000000000008036
12-27 16:06:13.513 20962 20962 F DEBUG   :     x8   0072006500640069  x9   0000000000000001  x10  0000000000000003  x11  00000000000000ff

12-27 16:06:13.514 20962 20962 F DEBUG   :
12-27 16:06:13.514 20962 20962 F DEBUG   : backtrace:
12-27 16:06:13.514 20962 20962 F DEBUG   :     #00 pc 0000000000028228  /data/app/com.chenxf.opengles-Xbv907eJgfjlz8Zq9XfKYQ==/base.apk (offset 0x3675000)

3.2 Análisis de causas

No hay pila, por lo que también es a través del registro para ver dónde se ejecuta al final. Aquí hay una lista de códigos:

class TextSample
{
    
    
public:
	TextSample();
	virtual ~TextSample();
	virtual void Init();
	virtual void Draw(int screenW, int screenH);

private:
	Shader *m_pShader;
};



TextSample::TextSample() {
    
    
}

void TextSample::Draw(int screenW, int screenH) {
    
    
    if(m_pShader == nullptr)
        return;

    DEBUG_LOGCATE();
    glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glClearColor(1.0, 1.0, 1.0, 1.0);
    // enable alpha blending
    // ------------
    DEBUG_LOGCATE();

    m_pShader->use();
}

El registro se bloquea en m_pShader->use().
¡Pero lo extraño es que se ha juzgado que el frente de la función está vacío!if(m_pShader == nullptr) return;

¿por qué? Debido a que
m_pShader está definido, pero no inicializado, a diferencia de JAVA, para C++, siempre que se genere un objeto TextSample, ¡el puntero interno de m_pShader no está vacío!

3.3 Soluciones

La solución es muy simple, en el constructor, ¡asegúrese de que el puntero esté inicializado!

TextSample::TextSample() {
    
    
    m_pShader = nullptr;
}

¡Esta es también la diferencia entre el trabajo de C++ y el trabajo de JAVA! JAVA no necesita preocuparse por los punteros. Se define una variable y no es necesario inicializarla. Está vacía de forma predeterminada.

Supongo que te gusta

Origin blog.csdn.net/newchenxf/article/details/121537539
Recomendado
Clasificación