Skip to content

Commit fd87648

Browse files
committed
Update tutorial
1 parent 9e501f1 commit fd87648

File tree

2 files changed

+233
-38
lines changed

2 files changed

+233
-38
lines changed

content/tutorial.mdx

Lines changed: 231 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2,60 +2,254 @@
22
title: "Tutorial"
33
description: "Tutorial for C Traceback"
44
author: "Ching-Yin Ng"
5-
date: "2025-12-30"
5+
date: "2025-12-31"
66
---
77

88
# Tutorial
99

10-
<Callout>This is an example of `layout:'full'`</Callout>
11-
12-
```typescript
13-
// app/_meta.global.tsx
14-
export default {
15-
contact: {
16-
type: 'page',
17-
theme: {
18-
layout: 'full',
19-
toc: false,
20-
timestamp: false,
21-
}
10+
<Callout>This tutorial is not finished yet</Callout>
11+
12+
## Project Setup
13+
14+
For demonstration, let us start with a simple vector calculation project.
15+
Below is the sample code written with C99. It does four things:
16+
17+
1. Allocate memory for vector.
18+
2. Initialize values for vector.
19+
3. Divide every vector element by denominator.
20+
4. Clean up.
21+
22+
Let us look at them one by one.
23+
```c
24+
/**
25+
* \file: project.c
26+
*/
27+
28+
#include <stdio.h>
29+
#include <stdlib.h>
30+
31+
#include "c_traceback.h"
32+
33+
int main(void)
34+
{
35+
const size_t n = 1000; // Vector size
36+
const double denominator = 123.0;
37+
38+
/* Allocate memory */
39+
40+
/* Initialize values */
41+
42+
/* Division */
43+
44+
/* Clean up */
45+
46+
return 0;
47+
48+
error_clean_up:
49+
/* Error clean up */
50+
51+
return 1;
52+
}
53+
```
54+
55+
## Allocate memory
56+
For demonstrative purpose, let us try allocating memory by using a function.
57+
Below is what I would write in C99:
58+
```c
59+
int alloc_memory(double **arr, const size_t n)
60+
{
61+
*arr = malloc(n * sizeof(double));
62+
if (!(*arr))
63+
{
64+
return 1; // Failed to allocate memory
65+
}
66+
return 0;
67+
}
68+
```
69+
While the function is fine for a simple project, it is better to have an error traceback
70+
and error message so that users know what happened without having to go through
71+
your source code.
72+
73+
### `RAISE_ERROR` <Badge text="Macro" />
74+
We can first make use of the `RAISE_ERROR` macro.
75+
Instead of returning a value, we raise an error instead.
76+
```c /void/ {6-7}
77+
void alloc_memory(double **arr, const size_t n)
78+
{
79+
*arr = malloc(n * sizeof(double));
80+
if (!(*arr))
81+
{
82+
// Failed to allocate memory
83+
RAISE_ERROR(CTB_MEMORY_ERROR, "Failed to allocate memory for vector!");
2284
}
2385
}
2486
```
87+
However, it doesn't do much by itself. It only silently records an error.
88+
We will have to modify some code in the `main` function.
89+
90+
### `TRACE` <Badge text="Macro" />
91+
On the outer scope, we can wrap our function call with `TRACE`, which
92+
returns an boolean error value. On top of that, `TRACE` will manage
93+
the call stack automatically for you.
94+
```c /TRACE/
95+
/* Allocate memory */
96+
double *arr;
97+
if (!TRACE(alloc_memory(&arr, n)))
98+
{
99+
goto error_clean_up;
100+
}
101+
```
102+
103+
### `TRY_GOTO` <Badge text="Macro" />
104+
`TRY_GOTO` does the same thing as `TRACE`, but it jumps to a label when
105+
the expression fails.
106+
```c /TRY_GOTO
107+
/* Allocate memory */
108+
double *arr;
109+
TRY_GOTO(alloc_memory(&arr, n), error_clean_up);
110+
```
111+
112+
## Clean up
113+
### `ctb_dump_traceback` <Badge text="Function" />
114+
Now, add `ctb_dump_traceback` at the error handling. It will log the traceback to `stderr`
115+
and reset the internal error status.
116+
```c
117+
int main(void)
118+
{
119+
/* Clean up */
120+
free(arr);
121+
return 0;
122+
123+
error_clean_up:
124+
/* Error clean up */
125+
free(arr);
126+
ctb_dump_traceback();
127+
return 1;
128+
}
129+
```
130+
Below is the final code. Lets set `n` to 1000000000000000 to see what happens.
131+
```c {10, 14, 19, 26, 31-32, 36-44}
132+
/**
133+
* \file: project.c
134+
*/
135+
136+
#include <stdio.h>
137+
#include <stdlib.h>
138+
139+
#include "c_traceback.h"
140+
141+
void alloc_memory(double **arr, const size_t n);
142+
143+
int main(void)
144+
{
145+
const size_t n = 1000000000000000; // Vector size
146+
const double denominator = 123.0;
147+
148+
/* Allocate memory */
149+
double *arr;
150+
TRY_GOTO(alloc_memory(&arr, n), error_clean_up);
151+
152+
/* Initialize values */
153+
154+
/* Division */
155+
156+
/* Clean up */
157+
free(arr);
158+
return 0;
159+
160+
error_clean_up:
161+
/* Error clean up */
162+
free(arr);
163+
ctb_dump_traceback();
164+
return 1;
165+
}
166+
167+
void alloc_memory(double **arr, const size_t n)
168+
{
169+
*arr = malloc(n * sizeof(double));
170+
if (!(*arr))
171+
{
172+
// Failed to allocate memory
173+
RAISE_ERROR(CTB_MEMORY_ERROR, "Failed to allocate memory for vector!");
174+
}
175+
}
25176

26-
We'd love to hear from you! Whether you have a question, feedback, or just want to say hello, feel free to reach out.
177+
```
178+
#### Output
179+
`n` is too big to be allocated on any single computer.
180+
You should see the traceback below.
181+
<Callout type="info">If you don't see the traceback, turn off optimization flags by using `-O0` as compilers could optimize the malloc away.</Callout>
182+
```ansi
183+
--------------------------------------------------
184+
Traceback (most recent call last):
185+
(#00) File "/Users/alvinng/Desktop/project/project.c", line 19 in main:
186+
alloc_memory(&arr, n)
187+
(#01) File "/Users/alvinng/Desktop/project/project.c", line 42 in alloc_memory:
188+
<Error raised here>
189+
MemoryError: Failed to allocate memory for vector!
190+
--------------------------------------------------
191+
```
27192

28-
## Get in Touch
29193

30-
You can contact us through any of the following methods:
31194

32-
### Email
33-
**General Inquiries:** [email protected]
34-
**Support:** [email protected]
35-
36195

37-
### Phone
38-
**Main Office:** +1 (555) 123-4567
39-
**Support Hotline:** +1 (555) 987-6543
196+
```c
197+
/**
198+
* \file: project.c
199+
*/
40200

41-
### Address
42-
123 Main Street
43-
Suite 100
44-
San Francisco, CA 94102
45-
United States
201+
#include <stdio.h>
202+
#include <stdlib.h>
46203

47-
## Business Hours
204+
int alloc_memory(double **arr);
205+
void division(double *arr, double denominator, const int n);
48206

49-
- **Monday - Friday:** 9:00 AM - 6:00 PM PST
50-
- **Saturday:** 10:00 AM - 4:00 PM PST
51-
- **Sunday:** Closed
207+
int main(void)
208+
{
209+
const int n = 1000; // Vector size
210+
const double denominator = 123.0;
52211

53-
## Contact Form
212+
/* Allocate memory */
213+
double *arr;
214+
if (!alloc_memory(&arr, n))
215+
{
216+
goto error;
217+
}
54218

55-
Fill out the form below and we'll get back to you within 24 hours:
219+
/* Initialize values */
220+
for (int i = 0; i < n; i++)
221+
{
222+
arr[i] = i;
223+
}
56224

57-
*(Contact form would be integrated here)*
225+
/* Do calculation */
226+
division(arr, denominator, n);
227+
228+
/* Clean up */
229+
free(arr);
230+
return 0;
231+
232+
error:
233+
/* Error clean up */
234+
free(arr);
235+
return 1;
236+
}
58237

59-
---
238+
int alloc_memory(double **arr, const int n)
239+
{
240+
*arr = malloc(N * sizeof(double));
241+
if (!(*arr))
242+
{
243+
return 1; // Failed to allocate memory
244+
}
245+
return 0;
246+
}
60247

61-
*We typically respond to all inquiries within 1-2 business days.*
248+
void division(double *arr, double denominator, const int n)
249+
{
250+
for (int i = 0; i < n; i++)
251+
{
252+
arr[i] /= denominator;
253+
}
254+
}
255+
```

mdx-components.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {useMDXComponents as getThemeComponents} from 'nextra-theme-docs';
2-
import {Callout, FileTree} from "nextra/components";
2+
import {Callout, FileTree, Tabs} from "nextra/components";
33

44
import { Badge } from "components/ui/badge";
55

@@ -13,5 +13,6 @@ export function useMDXComponents() {
1313
Badge: Badge,
1414
Callout: Callout,
1515
FileTree: FileTree,
16+
Tabs: Tabs,
1617
}
1718
}

0 commit comments

Comments
 (0)