You are here: Home > Uncategorized > Exception Handling Dalam Bahasa C

Exception Handling Dalam Bahasa C

Bahasa C tidak memberikan cara langsung untuk Exception Handling atau disebut Error Handling dalam C, tapi ada cara lainnya untuk melakukan error handling. Dalam Bahasa C, programmer itu diminta untuk mencegah error-error yang terjadi, dan menguji nilai return dari fungsi. Misalnya, banyak panggilan return -1 atau NULL pada beberapa fungsi kalau terjadi error seperti socket() (Unix Socket Programming) atau malloc() untuk mengindikasikan masalah yang perlu diketahui oleh si programmer. Jadi, pengujian yang cepat pada nilai return ini akan lebih mudah dilakukan misalnya dengan ‘if statement’.

Misalnya, kalau suatu program berhasil itu karena nilai return programnya itu nol. Kalau programnya error, biasanya dikarenakan angka yang lebih besar dari nol itu dikembalikan (misalnya 1). (Dengan command ‘echo $?’ di command line, kita bisa menampilkan kode return program yang sebelumnya dijalankan). Jadi, yang perlu diingat adalah, kita sebagai programmer bertanggung jawab atas error handling.

 

Fungsi errno, perror() dan strerror()

Bahasa C menyediakan fungsi perror() dan strerror() yang bisa digunakan untuk menampilkan pesan teks yang dihubungkan dengan errno.

Variabel Global errno digunakan oleh fungsi C dan integer ini telah ditentukan kalau ada error saat pemanggilan fungsi. Untuk menggunakan errno, kita perlu header file errno.h dan memanggil ‘extern int errno;

Fungsi perror() menampilkan string yang kita lempar kedalamnya, diikuti tanda kurung kurawal dan pesan teks nilai errno saat itu.

Fungsi strerror() mengembalikan pointer ke representasi teks nilai errno saat itu.

Mari coba menstimulasikan kondisi error dan coba buka file yang tidak ada. Pada contoh dibawah ini, kita akan mencoba menggunakan kedua fungsi tersebut, yaitu perror() dan strerror() untuk menampilkan penggunaannya. Kita bisa juga menggunakan salah satu atau lebih cara mengeluarkan atau mem-print kan error-error tersebut.

Perlu diingat, kalau kita harus menggunakan file stream stderr untuk mengeluarkan atau menampilkan semua error-error tersebut.

Contoh:

#include <stdio.h>
#include <errno.h>
#incude <string.h>

extern int errno;

int main()
{
FILE * fp;
fp = fopen(“not_exist_file.txt”, “rb”);
if (fp == NULL)
{
fprintf(stderr, “Value of errno: %d\n”, errno);
fprintf(stderr, “Error opening the file: %s\n”, strerror(errno));
perror(“Error printed by perror”);

}
else
fclose (fp);

return 0;
}

 

 

 

 

 

Output:

Value of errno: 2
Error opening the file: No such file or directory
Error printed by perror: No such file or directory

Untuk menggenerasikan error, kita membuka file yang tidak ada. Kalau file pointer (fp) sama dengan NULL, maka akan di print nilai errno. Kalau mendapatkan file pointer (kalau file nya ada) file nya akan ditutup.

Disini, pertama-tama kita memprint errno, kemudian menggunakan fungsi strerror() untuk memberikan pesan kita sendir dan menampilkan teks errno. Kemudian fungsi perror digunakan untuk memberikan pesan kita sendiri, diikuti dengan tanda kurung kurawal dan representasi teks errno.

Error Divide by Zero

Divide by Zero adalah salah satu error yang sering ditemukan. Error ini dikarenakan ada bilangan yang dibagi nol dalam program yang dibuat.  Contoh kode dibawah inilah yang akan menampilkan runtime error dan keluar dari program.

int dividen = 10;
int pembagi = 0;
int hasil;

hasil = dividen / pembagi; // Ini akan menampilkan runtime error!

 

Hal ini terjadi karena programmer  tidak mengecek kalau ada pembilang yang sama dengan nol dan hal ini akhirnya membuat runtime error. Karena itu, programmer harus memastikan kalau pembagi tidak pernah boleh nol.

Kode dibawah ini memperbaiki error diatas dengan mengecek kalau pembagi nya itu nol atau bukan sebelum dilakukan pembagiannya:

#include <stdio.h> //untuk fprintf dan stderr
#include <stdlib.h>

int main(void)
{
int dividen = 10;
int pembagi = 0;
int hasil;

if (pembagi == 0)
{
fprintf(stderr, “Pembaginya nol! Exit program. . .\n”);
exit(-1);
}

hasil = dividen / pembagi;
fprintf(stderr, “Hasil bagi : %d\n”, hasil);
exit(0);
}

 

 

Program Exit Status

Akan lebih baik untuk keluar dari program dengan nilai EXIT_SUCCESS dimana program keluar setelah operasi nya berhasil. Disini, EXIT_SUCCESS adalah macro yang didefinisikan sebagai 0. Kalau ada kondisi error dalam program, kita harus keluar dari program dengan status EXIT_FAILURE yang didefinisikan sebagai -1.

EXIT_SUCCESS dan EXIT_FAILURE itu didefinisikan dengan header file stdlib.h. Dibawah ini contoh penggunaannya:

#include <stdio.h> //untuk fprintf dan stderr
#include <stdlib.h> // untuk keluar dari program

int main(void)
{
int dividen = 10;
int pembagi = 0;
int hasil;

if (pembagi == 0)
{
fprintf(stderr, “Pembaginya nol! Exit program. . .\n”);
exit(EXIT_FAILURE);
}

hasil = dividen / pembagi;
fprintf(stderr, “Hasil bagi : %d\n”, hasil);
exit(EXIT_SUCCESS);
}

 

Signal Handling dalam Bahasa C

Signal adalah suatu kondisi yang dilaporkan saat mengeksekusi suatu program, dan bisa di abaikan saja. Biasanya signal itu merupakan sistem operasi yang menunjukkan error-error tertentu yang terjadi, seperti division by zero, interrupt, dll.

Namun, signal ini bukan digunakan untuk menangkap error-error yang ada; biasanya untuk menunjukkan error kritis yang akan mengganggu laju program yang normalnya.

Satu fungsi mengirim signal, fungsi lainnya digunakan untuk memastkan bagaimana suatu signal akan di proseskan. Banyak signal-signal ini yang dihasilkan oleh operasi sistem dan juga sebagai fungsi pengirim signal.

Signal itu didefinisikan dengan header signal.h. Selain di definisikan, fungsi signal() juga perlu dipanggil. Signal handler ini akan diperlukan untuk memastikan beberapa sumber itu sudah dibersihkan dengan baik sebelum program diakhiri.

IGABRT
       Terminasi abnormal, seperti yang dipicu oleh fungsi abort. (Abort)

SIGFPE
       Operasi arimatika error, seperti divide by 0 atau overflow. (Floating point expetion)

SIGILL
       Terdeteksinya ‘program objek yang invalid’. Biasanya karena ada instruksi illegal dalam
suatu program. (Illegal Instruction)

SIGINT
       Perhatian signal interaktif; pada sistem interaktif ini biasanya dihasilkan dengan mengetik
beberapa kunci ‘break-in’ di terminal. (Interrupt)

SIGSEGV
       Akses penyimpanan yang invalid; paling sering disebabkan karena menyimpan suatu nilai
dalam objek yang ditunjuk oleh pointer yang buruk. (Segment Violation)

SIGTERM
       Permintaan mengakhiri suatu program oleh program itu sendiri. (Terminate)

Beberapa implementasi memiliki tambahan signal yang namanya itu akan selalui dimulai dengan SIG, dan akan memiliki nilai yang unik. Fungsi signal memungkinkan kita untuk menentukan tindakan mana yang diambil pada penerimaan signal. Fungsi signal ini mengubah pointer dan mengembalikan nilai aslinya. Jadi, fungsi nya itu seperti ini:

#include <signal.h>

Void (*signal (int sig, void(*func)(int)))(int);

Fungsi kedua mengambil argument satu int dan mengembalikan void. Argumen kedua ke signal itu mirip dengan pointer ke fungsi yang mengembalikan void yang mengambil argument int.

Kalau panggilan ke signal berhasil, nilai fungsi sebelumnya untuk signal tertentu itu akan dikembalikan. Kalau tidak, SIG_ERR dikembalikan dan errno di set.

Ketika signal event terjadi, kalau dihubungkan dengan fungsi pointer ke fungsi, pertama, persamaan signal (sig, SIG_DFL) itu di eksekusi. Hal ini akan mereset signal handler menjadi default, yaitu menghentikan program. Kalau signalnya SIGILL, berarti soal reset ini merupakan implementasi yang didefinisikan. Implementasi ini bisa memilih untuk memblokir masukan lebih lanjut pada signal. Kemudian, fungsi signal-handling dipanggil. Kalau fungsi kembali secara normal, berarti programnya akan terus berlanjut. Namun, kalau nilai sig adalah SIGFPE, atau implementasi lainnya, berarti hal ini tidak terdefinisi.

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>

Static void catch_function(int signal)
{
puts(“Interactive attention signal caught.”);
}

int main(void)
{
if (signal(SIGINT, catch_function) == SIG_ERR)
{
fputs(“An error occurred while setting a signal handler.\n”, stderr);
return EXIT_FAILURE;
}

puts(“Raising the interactive attention signal.”);

if (raise(SIGINT) != 0)
{
fputs(“An error occurred while setting a signal handler.\n”, stderr);
return EXIT_FAILURE;
}

puts(“Exiting.”);
return 0;
}

Berikut adalah contoh penggunaan signal handler:

#include <signal.h>

int raise (int sig);

 

Suatu program dapat mengirimkan signal ke dirinya sendiri dengan fungsi raise yang ditulis seperti ini:

#include <signal.h>

void
abort (void)
{
raise(SIGABRT)
}

 

Dimana signal sig dikirim ke program. Raise mengembalikan nol
kalau sukses, non-zeru sebaliknya. Fungsi library abort itu
diimplementasikan sebagai berikut:

Kalau signal nya terjadi buat alsan lain selain memanggil abort atau raise, fungsi signal-handling hanya akan memanggil signal atau memberikan nilai ke objek static tipe sig_atomic_t. Tipe sig_atomic_t itu di deklarasikan dalam <signal.h>. Tipe tersebut hanyalah tipe objek yang bisa di modifikasi sebagai kesatuan atomic yang aman. Tapi, fungsi ini tidak mengikuti aturan Standard.

Setjmp

Fungsi setmp bisa digunakan untuk meniru fitur yang menangani exception pada Bahasa pemrograman yang lain. Panggilan pertama setjmp memberikan titik referensi untuk mengembalikan fungsi yang diberikan, dan valid selama fungsi yang memiliki setjmp() tidak kembali atau keluar. Kalau kita memanggil longjmp, itu bisa menyebabkan eksekusi untuk kembali ke titik dimana setjmp dipanggil. Berikut contohnya:

#include <stdio.h>
#include <setjmp.h>

Jmp_buf test;

void tryjump()
{
longjmp(test, 3);
}

 

Int main(void)
{
if (setjmp(test) == 0)
{
printf(“setjmp() returned 0”);
tryjum();
}

else
printf(“setjmp() returned from a longjmp function call”);
}

 

Nilai variabel yang tidak dapat berubah bisa saja corrupt ketika setjmp kembali dari panggilan longjmp.

Selama setjmp() dan longjmp() bisa digunakan untuk error handling, biasnya lebih digunakan untuk mengembalikn nilai suatu fungsi untuk menunjukkan sebuah error.

 

Sources

https://www.codingunit.com/c-tutorial-error-handling-exception-handling

https://www.tutorialspoint.com/cprogramming/c_error_handling.htm

https://en.wikibooks.org/wiki/C_Programming/Error_handling

http://publications.gbdirect.co.uk/c_book/chapter9/signal_handling.html

 

  • Digg
  • Del.icio.us
  • StumbleUpon
  • Reddit
  • Twitter
  • RSS

Leave a Reply