Skip to main content

How to use gdb in Ubuntu Terminal

Here's a practical, minimal guide for using GDB in Ubuntu terminal — from launching to setting breakpoints and navigating your code. 🧰 Step 1: Compile with Debug Symbols Use -g and disable optimizations ( -O0 preferred for debugging): bash Copy Edit g++ -g -O0 -o myprog myprog.cpp 🚀 Step 2: Launch GDB bash Copy Edit gdb ./myprog You'll see a (gdb) prompt. 🎯 Step 3: Set Breakpoints You can set breakpoints in three main ways : ✅ a. At a function gdb Copy Edit (gdb) break main ✅ b. At a specific file and line gdb Copy Edit (gdb) break myprog.cpp:42 ✅ c. At a method in a class gdb Copy Edit (gdb) break MyClass::doSomething If the symbol is mangled (C++), GDB usually demangles automatically, especially if compiled with -g . ▶️ Step 4: Run the Program gdb Copy Edit (gdb) run 🧭 Step 5: Navigate Command Meaning next or n Step over current line step or s Step into function call finish Run until current function returns continue or c Continue until...

C pointer example

1/5 Query?

int *i=//heap var allocated

int*trackI=i;

free(i);

now track==NULL?

---

int *i=//heap var allocated

int*trackI=i;

free(trackI);

now i==NULL?

1/5
ChatGPT said:
ChatGPT

In both cases:

Case 1:

c
int *i = // heap var allocated int *trackI = i; free(i);

After freeing i, the trackI pointer still points to the same memory address (which is now invalid because the memory has been freed), but trackI is not automatically set to NULL. Similarly, i is also not automatically set to NULL, so both i and trackI are dangling pointers, pointing to freed memory.

If you want to avoid dangling pointers, you need to manually set them to NULL:

c
free(i); i = NULL; trackI = NULL;

Case 2:

c
int *i = // heap var allocated int *trackI = i; free(trackI);

In this case, you are freeing the memory using trackI. However, the same rule applies: neither i nor trackI is automatically set to NULL. So, both will still point to the freed memory address, resulting in dangling pointers.

To avoid this, you should explicitly set trackI and i to NULL after freeing the memory:

c
free(trackI); i = NULL; trackI = NULL;

Summary:

  • Freeing a pointer does not automatically set it (or other pointers pointing to the same memory) to NULL. You must do that manually to avoid dangling pointers.

================================
2/5 Query?

int *i=//heap var allocated

int*trackI=i;

free(i);

i=NULL

now track==NULL?

---

int *i=//heap var allocated

int*trackI=i;

free(trackI);

trackI=NULL:

now i==NULL?

2/5
ChatGPT said:
ChatGPT

In C, when you set i = NULL or trackI = NULL, only the specific pointer variable is affected. This means that modifying one pointer variable (e.g., i) does not affect the other pointer (e.g., trackI) that points to the same memory location.

Here's a breakdown of each case:

Case 1:

c
int *i = malloc(sizeof(int)); // Allocate heap memory int *trackI = i; // Both i and trackI point to the same memory location free(i); // Free the memory pointed to by i (and by trackI, since they are pointing to the same address) i = NULL; // Set i to NULL, but trackI still holds the original address // Now: i == NULL, but trackI != NULL

In this case, trackI still holds the original memory address, but since the memory has been freed, accessing it through trackI would lead to undefined behavior. trackI is not automatically set to NULL when you set i = NULL.

Case 2:

c
int *i = malloc(sizeof(int)); // Allocate heap memory int *trackI = i; // Both i and trackI point to the same memory location free(trackI); // Free the memory pointed to by trackI (which is the same as i) trackI = NULL; // Set trackI to NULL, but i still holds the original address // Now: trackI == NULL, but i != NULL

In this case, i is still pointing to the freed memory (a dangling pointer), but trackI is NULL. Accessing i would also lead to undefined behavior.

Conclusion:

Setting one pointer to NULL does not automatically set other pointers pointing to the same memory to NULL. Each pointer variable must be set to NULL individually after freeing memory to avoid dangling pointers.

=====================================

3/5 Query?

int *i=//heap var allocated

void*trackI=i;

free(i);

i=NULL

now if I using some difft fn where I will add trackI, how will I check if heap already cleared?

---

int *i=//heap var allocated

void*trackI=i;

free(trackI);

trackI=NULL:

So heap for *i already cleared. But since i not yet set trackI to NULL, how will I check before freeing i?

3/5
ChatGPT said:
ChatGPT

In C, there’s no built-in mechanism to check whether memory has already been freed. Once you free a pointer (like i), it’s important to set both i and any other pointer (like trackI) referencing that memory to NULL to avoid potential issues like double-freeing or accessing invalid memory.

Here’s a breakdown of how you can manage this safely:

Problem Overview

  • When you free i, the memory is released, but trackI still holds the original address, which is no longer valid.
  • If you try to free trackI without knowing it has already been freed (via i), it could lead to undefined behavior (e.g., double free error).

Solution: Set Pointers to NULL after Freeing

To avoid this, always ensure that all pointers referencing the same heap memory are set to NULL after freeing. A simple way to handle this is to use a helper function that sets all related pointers to NULL after freeing the memory.

Example Solution

Helper Function to Free and Nullify Multiple Pointers

c
void safe_free(void** ptr1, void** ptr2) { if (*ptr1) { free(*ptr1); // Free memory pointed by ptr1 *ptr1 = NULL; // Set ptr1 to NULL } if (ptr2 && *ptr2) { *ptr2 = NULL; // Also set ptr2 to NULL if it's pointing to the same memory } }

Usage

c
int* i = (int*)malloc(sizeof(int)); // Allocate memory void* trackI = i; // Another pointer tracking the same memory // Free memory and set both pointers to NULL safely safe_free((void**)&i, (void**)&trackI); // Now both i and trackI are NULL, so no accidental double free

Explanation

  • safe_free() takes two pointer references (void**), allowing it to modify the original pointers and set them to NULL.
  • After calling safe_free(), both i and trackI will be NULL, ensuring that you don't accidentally free already-freed memory.

General Guidelines:

  • Always set freed pointers to NULL: This ensures that you can check whether a pointer is still valid by checking if it’s NULL.
  • Use helper functions for safety: A function like safe_free() can ensure that all references to the same memory are handled consistently, reducing the chance of double freeing or invalid memory access.

With this approach, you'll avoid the issue of accidentally freeing memory twice or accessing invalid memory.

=================================

4/5 Query?

void fn(){

int *i=//heap var allocated

void*trackI=i;

free(i);

i=NULL

}

now if I never set trackI=NULL (i know it won't be used any further) I think it wont cause any memory lekage issue once control moves out of scope of fn

---

void fn(){

int *i=//heap var allocated

void*trackI=i;

free(trackI);

trackI=NULL:

}

So heap for *i already cleared. But if never set i=NULL I dont think it will be any issue once control moves out of scope of fn

4/5
ChatGPT said:
ChatGPT

You are correct that in both scenarios, there won't be memory leakage issues after the function returns, but let's clarify how memory and pointers work in these cases:

1. Heap Memory Allocation and trackI Pointer:

c
void fn() { int *i = // heap var allocated void* trackI = i; // track pointer points to the same heap memory free(i); // heap memory is deallocated i = NULL; // i is set to NULL }
  • After you call free(i), the heap memory that i was pointing to is deallocated.
  • Even though trackI still points to the deallocated memory (dangling pointer), once the function exits, both i and trackI go out of scope, and there are no more references to that memory.
  • As a result, no memory leak occurs. The memory is freed, and neither i nor trackI is accessible after the function exits.

Conclusion: Not setting trackI = NULL after freeing i will not cause a memory leak. It's just a dangling pointer, and since it goes out of scope after the function ends, it won't cause issues.


2. Freeing Memory via trackI Pointer:

c
void fn() { int *i = // heap var allocated void* trackI = i; // track pointer points to the same heap memory free(trackI); // memory is deallocated via trackI trackI = NULL; // trackI is set to NULL }
  • In this case, you are freeing the memory via trackI, which deallocates the same heap memory that i was pointing to.
  • Even though you don't set i = NULL, this won’t cause a memory leak. When the function exits, i goes out of scope and is no longer accessible.
  • The heap memory is correctly deallocated regardless of i not being set to NULL.

Conclusion: Not setting i = NULL will not cause a memory leak. After the function exits, i will no longer exist, and since the memory was already freed, there's no problem.


General Notes:

  • Dangling pointers: If you don't set a pointer to NULL after freeing the memory, it becomes a dangling pointer, meaning it points to memory that has already been freed. Accessing this pointer can cause undefined behavior. However, once the function returns, any local variables (like i and trackI) go out of scope, so this won’t be an issue.

  • Best practice: It is always good practice to set a pointer to NULL after freeing it, especially in larger or more complex programs, to avoid any accidental usage of dangling pointers. But in your specific examples, since the function scope ends, it's not necessary to set them to NULL.

=============================
5/5. Query?
void fn(){

int *i=//heap var allocated

void**trackI=&i;

free(i);

i=NULL

}

now *trackI==NULL?

---

void fn(){

int *i=//heap var allocated

void**trackI=&i;

free(*trackI);

*trackI=NULL:

}

now i==NULL? 
-------------------------------------
ChatGPT said:

ChatGPT

Let’s break down both examples:

Example 1

c
void fn() { int *i = malloc(sizeof(int)); // heap memory allocated void **trackI = (void**)&i; // tracking `i` by reference through a pointer to `i` free(i); // free heap memory pointed by `i` i = NULL; // set `i` to NULL // Now, *trackI == NULL? }
  • After free(i), the memory pointed to by i is deallocated.
  • Then, i = NULL; sets i to NULL.
  • Since trackI points to i, the statement *trackI == NULL will evaluate to true because trackI indirectly references i, which was set to NULL.

So yes, after setting i = NULL, *trackI will also be NULL because trackI points to i.


Example 2

c
void fn() { int *i = malloc(sizeof(int)); // heap memory allocated void **trackI = (void**)&i; // tracking `i` by reference through a pointer to `i` free(*trackI); // free the memory pointed to by `*trackI` (same as `i`) *trackI = NULL; // set `*trackI` (which is `i`) to NULL // Now, i == NULL? }
  • free(*trackI); is equivalent to free(i);, so it frees the memory pointed to by i.
  • Then, *trackI = NULL; sets *trackI, which is i, to NULL.

Thus, i will be NULL after this because trackI points to i, and *trackI = NULL sets i to NULL.


In both cases, after deallocating the memory, i is successfully set to NULL via either direct assignment or through trackI.

Comments

Popular posts from this blog

Ubuntu Notes: Set up autossh as systemd useful-reminder commands

 sudo vim /etc/systemd/system/permanentAutossh.service ======================================== [Unit] Description=Keeps a tunnel to myOciFreeNat open After=network-online.target [Service] User=<username> Environment="AUTOSSH_GATETIME=0" ExecStart=/usr/bin/autossh -M 0 -q -N -o "ServerAliveInterval 60" -o "ServerAliveCountMax 3" -L 4322:127.0.0.1:5432 -i /<ssh_private_key_file_absolute_path> <username>@<ip_address> -p 22 [Install] WantedBy=multi-user.target ======================================== sudo systemctl daemon-reload sudo systemctl enable permanentAutossh sudo systemctl start permanentAutossh ================== sudo systemctl daemon-reload sudo systemctl restart permanentAutossh sudo systemctl status permanentAutossh ====================== sudo systemctl stop permanentAutossh sudo systemctl disable permanentAutossh sudo rm /etc/systemd/system/permanentAutossh.service

syslog cpp programming: learning using chatGcp

  Introduction to Syslog C++ August 27, 2024 This conversation may reflect the link creator’s personalized data, which isn’t shared and can meaningfully change how the model responds. You said: I am new to syslog in cpp programming n just starting. Can you teach me ChatGPT said: ChatGPT Sure! syslog is a standard for logging system messages in Unix-like operating systems. It provides a way to send log messages to the system log, which can then be collected and analyzed by various tools. Here's a basic guide to get you started with syslog in C++: 1. Include the Necessary Header To use syslog , you need to include the syslog.h header: cpp Copy code # include <syslog.h> 2. Open the Connection to syslog Before sending log messages, you need to open a connection to the syslog system. This is typically done at the start of your program: cpp Copy code openlog ( "your_program_name" , LOG_PID | LOG_CONS, LOG_USER); "your_program_name" : A string representing ...

Ubuntu - C++ Notes: Install & update boost c++ library from git (may contain some error in process mentioned below)

 Boost C++ Library Installation from git in ubuntu: 1. create a directory named boost in your desired location and go to that directory mkdir boost;cd boost; 2. clone boost recursively from git using command git clone --recursive https://github.com/boostorg/boost.git 3. cd boost; sudo ./bootstrap.sh; 4. sudo ./b2; 5. sudo ./b2 install; DONE! --------------------------- Boost C++ Library Update Verson from git in Ubuntu: 1. go to gitDownloads/boost directory cd gitDownloads/boost; 2. git pull; 3. git submodule update --recursive; 4. cd boost; sudo ./bootstrap.sh; 5. sudo ./b2; 6. sudo ./b2 install; DONE!