Elección de los símbolos públicos que se van a quitar
PDBCopy proporciona las opciones -f y -F para que pueda quitar un conjunto arbitrario de símbolos públicos de un archivo de símbolos quitado, dejando solo los símbolos a los que la audiencia necesita acceder para realizar su depuración.
Un uso común de PDBCopy es crear una versión especial del archivo de símbolos para su uso por Parte de Microsoft en su programa de análisis de bloqueos en línea (OCA). OCA puede designar determinadas funciones como inertes, lo que significa que si la función se encuentra en el seguimiento de la pila, se omite. Normalmente, una función se declararía inert si es simplemente un contenedor o una función de "paso a través" que no realiza cálculos significativos. Si dicha función se encuentra en la pila en un análisis de errores, se puede suponer que esta propia función no estaba en error y, como máximo, pasó datos no válidos o dañados que recibió de rutinas anteriormente en la pila. Al omitir estas funciones, OCA puede determinar mejor la causa real del error o daños.
Naturalmente, cualquier función que desee declarar "inert" debe incluirse en la tabla de símbolos públicos del archivo de símbolos usado por OCA. Sin embargo, no son las únicas funciones que deben incluirse, como se muestra en el ejemplo siguiente.
Supongamos que escribe un controlador de Windows y usa PDBCopy para quitar todos los símbolos públicos de su archivo de símbolos, excepto functionOne y FunctionSix, dos funciones inertes. Su expectativa es que, si FunctionOne o FunctionSix se encuentran en la pila después de un bloqueo, OCA los omitirá. Si alguna otra parte del controlador está en la pila, Microsoft le proporcionará la dirección de memoria correspondiente y puede usar la dirección para depurar el controlador.
Sin embargo, supongamos que el controlador ocupa la memoria en el siguiente diseño:
Dirección | Contenido de la memoria |
---|---|
0x1000 |
Dirección base del módulo |
0x2000 |
Principio de FunctionOne |
0x203F |
Fin de FunctionOne |
0x3000 |
Principio de FunctionSix |
0x305F |
Fin de FunctionSix |
0x7FFF |
Fin del módulo en memoria |
Si el depurador encuentra una dirección en la pila, selecciona el símbolo con la siguiente dirección inferior. Dado que la tabla de símbolos públicos contiene la dirección de cada símbolo, pero no hay ninguna manera de que el depurador sepa si una dirección está dentro de los límites de cualquier símbolo específico.
Por lo tanto, si se produce un error en la dirección 0x2031, el depurador ejecutado por Microsoft OCA identifica correctamente el error como si estuviera en FunctionOne. Dado que se trata de una función inert, el depurador continúa caminando por la pila para encontrar la causa del bloqueo.
Sin embargo, si se produce un error en 0x2052, el depurador sigue coincidendo con esta dirección a FunctionOne, aunque se encuentra más allá del final real de esta función (0x203F).
Por lo tanto, debe incluir en el archivo de símbolos eliminado no solo las funciones que desea exponer, sino también los símbolos inmediatamente después de estas funciones. En este ejemplo, desearía exponer FunctionOne, FunctionTwo, FunctionSix y FunctionSeven:
Dirección | Contenido de la memoria |
---|---|
0x1000 |
Dirección base del módulo |
0x2000 |
Principio de FunctionOne |
0x203F |
Fin de FunctionOne |
0x2040 |
Principio de FunctionTwo |
0x3000 |
Principio de FunctionSix |
0x305F |
Fin de FunctionSix |
0x3060 |
Principio de FunctionSeven |
0x7FFF |
Fin del módulo en memoria |
Si incluye las cuatro funciones en el archivo de símbolos eliminados, el análisis de OCA de Microsoft no tratará erróneamente la dirección 0x2052 como parte de FunctionOne. En este ejemplo se supone que esta dirección forma parte de FunctionTwo, pero eso no es importante porque no ha registrado FunctionTwo con OCA como una función inert. Lo importante es que la dirección 0x2052 se reconoce como no dentro de una función inert y, por lo tanto, OCA lo reconocerá como un error significativo dentro del controlador y puede informarle del error.
Si no desea publicitar los nombres de las funciones que siguen a cada función inert, puede insertar funciones no importantes en el código después de cada función inert para que los nombres de estas funciones se puedan incluir en el archivo de símbolos público. Asegúrese de comprobar que estas funciones agregadas siguen realmente las funciones inertes en el espacio de direcciones del binario, ya que algunas rutinas de optimización pueden modificar esto o incluso quitar algunas funciones por completo.