Skip to content

Commit

Permalink
fix: improve readability and translation in chapter 9
Browse files Browse the repository at this point in the history
  • Loading branch information
ivanlynch committed Mar 3, 2024
1 parent 0edbcfd commit b669166
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 106 deletions.
133 changes: 66 additions & 67 deletions src/ch09-01-unrecoverable-errors-with-panic.md
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
## Errores irrecuperables con `panic!`

A veces, sucede algo malo en su código y no hay nada que pueda hacer al
respecto. En estos casos, Rust tiene la macro `panic!`. Hay dos formas de
causar un panic en la práctica: tomando una acción que hace que nuestro código
entre en pánico (como acceder a una matriz más allá del final) o llamando
explícitamente a la macro `panic!`. En ambos casos, causamos un pánico en
nuestro programa. De forma predeterminada, estos pánicos imprimirán un mensaje
de error, desenrollarán, limpiarán la pila y se cerrarán. A través de una
variable de entorno, también puede hacer que Rust muestre la pila de llamadas
cuando ocurre un pánico para facilitar el seguimiento de la fuente del panic.

> ### Desenrollar el Stack o Abortar en respuesta a un Panic
respecto. En estos casos, Rust tiene la macro `panic!`. Hay dos formas de causar
un panic en la práctica: tomando una acción que hace que nuestro código entre en
pánico (como acceder a una matriz más allá del final) o llamando explícitamente
a la macro `panic!`. En ambos casos, causamos un pánico en nuestro programa. De
forma predeterminada, estos pánicos imprimirán un mensaje de error, se desharán,
limpiarán la pila y se cerrarán. A través de una variable de entorno, también
puede hacer que Rust muestre la pila de llamadas cuando ocurre un pánico para
facilitar el seguimiento de la fuente del panic.

> ### Deshacer la pila o abortar en respuesta a un pánico
>
> Por defecto, cuando ocurre un panic, el programa comienza a _desenrollar_,
> lo que significa que Rust retrocede por la pila y limpia los datos de cada
> Por defecto, cuando ocurre un panic, el programa comienza a _deshacerse_, lo
> que significa que Rust retrocede por la pila y limpia los datos de cada
> función que encuentra. Sin embargo, este retroceso y limpieza es mucho
> trabajo. Rust, por lo tanto, le permite elegir la alternativa de _abortar_
> inmediatamente, lo que termina el programa sin limpiar.
>
> La memoria que el programa estaba usando deberá ser limpiada
> por el sistema operativo. Si en su proyecto necesita hacer que el binario
> resultante sea lo más pequeño posible, puede cambiar de desenrollar a abortar
> al producir un pánico agregando `panic = 'abort'` a las secciones
> `[profile]` apropiadas en su archivo _Cargo.toml_. Por ejemplo, si desea
> abortar en caso de pánico en el modo de lanzamiento, agregue esto:
> La memoria que el programa estaba usando deberá ser limpiada por el sistema
> operativo. Si en su proyecto necesita hacer que el binario resultante sea lo
> más pequeño posible, puede cambiar de deshacer el programa a abortarlo al
> producir un pánico agregando `panic = 'abort'` a las secciones `[profile]`
> apropiadas en su archivo _Cargo.toml_. Por ejemplo, si desea abortar en caso
> de pánico en el modo de lanzamiento, agregue esto:
>
> ```toml
> [profile.release]
Expand All @@ -45,25 +45,25 @@ Cuando ejecutes el programa, verás algo como esto:
```

La llamada a `panic!` causa el mensaje de error contenido en las dos últimas
líneas. La primera línea muestra nuestro mensaje de panic y el lugar en
nuestro código fuente donde ocurrió el panic: _src/main.rs:2:5_ indica que es
la segunda línea, quinto carácter de nuestro archivo _src/main.rs_.
líneas. La primera línea muestra nuestro mensaje de panic y el lugar en nuestro
código fuente donde ocurrió el panic: _src/main.rs:2:5_ indica que es la segunda
línea, quinto carácter de nuestro archivo _src/main.rs_.

En este caso, la línea indicada es parte de nuestro código, y si vamos a esa
línea, vemos la llamada a la macro `panic!`. En otros casos, la llamada a
`panic!` podría estar en el código que nuestro código llama, y el nombre de
archivo y el número de línea informados por el mensaje de error serán el
código de otra persona donde se llama a la macro `panic!`, no la línea de
nuestro código que finalmente condujo a la llamada a `panic!`. Podemos usar la
traza de las funciones de las que provino la llamada a `panic!` para
determinar la parte de nuestro código que está causando el problema.
Discutiremos las trazas en más detalle a continuación.
archivo y el número de línea informados por el mensaje de error serán el código
de otra persona donde se llama a la macro `panic!`, no la línea de nuestro
código que finalmente condujo a la llamada a `panic!`. Podemos usar el backtrace
de las funciones de las que provino la llamada a `panic!` para determinar la
parte de nuestro código que está causando el problema. Discutiremos el backtrace
en más detalle a continuación.

### Usando un Backtrace de `panic!`
### Usando el backtrace de `panic!`

Veamos otro ejemplo de cómo es cuando una llamada a `panic!` proviene de una
biblioteca debido a un error en nuestro código en lugar de que nuestro código
llame directamente a la macro. La lista 9-1 tiene algún código que intenta
llame directamente a la macro. El listado 9-1 tiene algún código que intenta
acceder a un índice en un vector más allá del rango de índices válidos.

<span class="filename">Filename: src/main.rs</span>
Expand All @@ -72,22 +72,22 @@ acceder a un índice en un vector más allá del rango de índices válidos.
{{#rustdoc_include ../listings/ch09-error-handling/listing-09-01/src/main.rs}}
```

<span class="caption">Listing 9-1: Intentando acceder a un elemento más allá del
<span class="caption">Listado 9-1: Intentando acceder a un elemento más allá del
fin de un vector, que provocará una llamada a `panic!`</span>

Aquí, estamos intentando acceder al elemento 100 de nuestro vector (que está
en el índice 99 porque el indexado comienza en cero), pero el vector solo
tiene 3 elementos. En esta situación, Rust entrará en pánico. Usar `[]` se
supone que devuelve un elemento, pero si pasa un índice no válido, no hay
ningún elemento que Rust podría devolver aquí que sea correcto.
Aquí, estamos intentando acceder al elemento 100 de nuestro vector (que está en
el índice 99 porque el indexado comienza en cero), pero el vector solo tiene 3
elementos. En esta situación, Rust entrará en pánico. Usar `[]` se supone que
devuelve un elemento, pero si pasa un índice no válido, no hay ningún elemento
que Rust podría devolver aquí que sea correcto.

En C, intentar leer más allá del final de una estructura de datos es un
undefined. Podría obtener lo que está en la ubicación de
memoria que correspondería a ese elemento en la estructura de datos, aunque
la memoria no pertenece a esa estructura. Esto se llama _buffer overread_ y
puede provocar vulnerabilidades de seguridad si un atacante puede manipular el
índice de tal manera que lea datos que no debería estar permitido que se
almacenen después de la estructura de datos.
undefined. Podría obtener lo que está en la ubicación de memoria que
correspondería a ese elemento en la estructura de datos, aunque la memoria no
pertenece a esa estructura. Esto se llama _buffer overread_ y puede provocar
vulnerabilidades de seguridad si un atacante puede manipular el índice de tal
manera que lea datos que no debería estar permitido que se almacenen después de
la estructura de datos.

Para proteger su programa de este tipo de vulnerabilidad, si intenta leer un
elemento en un índice que no existe, Rust detendrá la ejecución y se negará a
Expand All @@ -99,18 +99,18 @@ continuar. Intentémoslo y veamos:

Este error apunta a la línea 4 de nuestro `main.rs` donde intentamos acceder al
índice 99. La siguiente línea de nota nos dice que podemos establecer la
variable de entorno `RUST_BACKTRACE` para obtener una traza de exactamente lo
que sucedió para causar el error. Una _traza_ es una lista de todas las
funciones que se han llamado para llegar a este punto. Las trazas en Rust
funcionan como lo hacen en otros lenguajes: la clave para leer la traza es
comenzar desde la parte superior y leer hasta que vea archivos que escribió.
Ese es el lugar donde se originó el problema. Las líneas por encima de ese
punto son el código que su código ha llamado; las líneas a continuación son el
código que llamó a su código. Estas líneas antes y después pueden incluir
código de Rust core, código de biblioteca estándar o cajas que está usando.
Intentemos obtener una traza estableciendo la variable de entorno
`RUST_BACKTRACE` a cualquier valor excepto 0. La lista 9-2 muestra una salida
similar a la que verás.
variable de entorno `RUST_BACKTRACE` para obtener el backtrace de exactamente lo
que sucedió para causar el error. El _Backtrace_ es una lista de todas las
funciones que se han llamado para llegar a este punto. El backtrace en Rust
funciona como lo hacen en otros lenguajes: la clave para leer el backtrace es
comenzar desde la parte superior y leer hasta que vea archivos que escribió. Ese
es el lugar donde se originó el problema. Las líneas por encima de ese punto son
el código que su código ha llamado; las líneas a continuación son el código que
llamó a su código. Estas líneas antes y después pueden incluir código de Rust
core, código de biblioteca estándar o crates que estés usando. Intentemos
obtener el backtrace estableciendo la variable de entorno `RUST_BACKTRACE` a
cualquier valor excepto 0. El listado 9-2 muestra una salida similar a la que
verás.

<!-- manual-regeneration
cd listings/ch09-error-handling/listing-09-01
Expand Down Expand Up @@ -142,31 +142,30 @@ stack backtrace:
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
```

<span class="caption">Listing 9-2: El backtrace generado por una llamada a
<span class="caption">Listado 9-2: El backtrace generado por una llamada a
`panic!` se muestra cuando la variable de entorno `RUST_BACKTRACE` está
configurada</span>

¡Eso es mucho resultado! La salida exacta que vea puede ser diferente según su
sistema operativo y la versión de Rust. Para obtener trazas con esta
información, deben estar habilitados los símbolos de depuración. Los símbolos
de depuración están habilitados de forma predeterminada cuando se usa `cargo
build` o `cargo run` sin el indicador `--release`, como tenemos aquí.
sistema operativo y la versión de Rust. Para obtener el backtrace con esta
información, deben estar habilitados los símbolos de depuración. Los símbolos de
depuración están habilitados de forma predeterminada cuando se usa `cargo build`
o `cargo run` sin el indicador `--release`, como tenemos aquí.

En la salida en la Lista 9-2, la línea 6 de la traza apunta a la línea en
En la salida en el listado 9-2, la línea 6 del backtrace apunta a la línea en
nuestro proyecto que está causando el problema: la línea 4 de `src/main.rs`. Si
no queremos que nuestro programa entre en pánico, debemos comenzar nuestra
investigación en la ubicación señalada por la primera línea que menciona un
archivo que escribimos. En la Lista 9-1, donde escribimos deliberadamente un
archivo que escribimos. En la listado 9-1, donde escribimos deliberadamente un
código que entraría en pánico, la forma de solucionar el pánico es no solicitar
un elemento más allá del rango de los índices del vector. Cuando su código
entra en pánico en el futuro, deberá averiguar qué acción está tomando el
código con qué valores para causar el pánico y qué debería hacer el código en
su lugar.
un elemento más allá del rango de los índices del vector. Cuando su código entra
en pánico en el futuro, deberá averiguar qué acción está tomando el código con
qué valores para causar el pánico y qué debería hacer el código en su lugar.

¡Volveremos a `panic!` y cuándo deberíamos y no deberíamos usar `panic!` para
manejar las condiciones de error en la sección [“To `panic!` or Not to
`panic!`][to-panic-or-not-to-panic]<!-- ignore --> más adelante en este
capítulo. A continuación, veremos cómo recuperarnos de un error usando
`Result`.
capítulo. A continuación, veremos cómo recuperarnos de un error usando `Result`.

[to-panic-or-not-to-panic]: ch09-03-to-panic-or-not-to-panic.html#panic-o-no-panic
[to-panic-or-not-to-panic]:
ch09-03-to-panic-or-not-to-panic.html#panic-o-no-panic
Loading

0 comments on commit b669166

Please sign in to comment.