Magic Lantern Firmware Wiki

This is a guide for developers who want to enhance Magic Lantern.

Since you can't run the Magic Lantern code step by step inside the camera, debugging may be a little difficult. This page will try to help.

Some simple debugging tools:

  • DebugMsg (DryOS call) and DEBUG() macro (wrapper around DebugMsg): these write a message to the internal camera log; DebugMsg is also used by Canon functions)
  • bmp_printf (Magic Lantern function, writes a message on the screen)
  • Dumping data from RAM
  • Script console (console.c; for now, only present in LUA-enabled build)

DebugMsg and DEBUG() macro[]

Juicy info here:

Call examples[]

  • DebugMsg:
DebugMsg(DM_MAGIC, 3, "This is a message")
DebugMsg(DM_MAGIC, 3, "This is an integer: %d", 5)
  • DEBUG macro:

This is a very handy wrapper around DebugMsg; recommended for all new development. It will print the function name and line number, and then your message (which is optional).

DEBUG();                 // prints only function name and line number
DEBUG("x=%d", x);        // prints also a printf-like string

This was defined by Trammell for debugging LUA code, and it's included in dryos.h in latest 550D builds.

How to use[]

To see the output messages, you have to call dumpf(). In the menu, Debug->Dump dmlog does that.

If you don't have acces to the menu, the simplest way to do this is to write this into the config file (usually magic.cfg):

debug.timed-dump = 10

This means Magic Lantern will call dumpf() in 10 seconds after booting. After the card activity light turns off, remove the card, put it into the card reader and you'll find a debugging log like this one: [1]. The debug log will contain Magic Lantern calls interleaved with Canon's DebugMsg's.

If there are too many debug messages, the log file will be trimmed. To inhibit some them, put this in debug.c, dump_task:

dm_set_store_level( DM_DISP, 7 );
dm_set_store_level( DM_LVFD, 7 );
dm_set_store_level( DM_LVCFG, 7 );
dm_set_store_level( DM_LVCDEV, 7 );

and those messages won't appear in the log file any more.

7 is a magic number and seems to work :)

DebugMsg codes[]

 50 [MAGIC]      # ./debug.h:64:#define DM_MAGIC	50 // Replaces PTPCOM with MAGIC
 24 [IMP]
130 [DISP]
131 [GUI]
156 [MC]
... (lots of codes) ...


This is for writing messages on the screen, and is documented here:

Note that after writing a message, it might be erased by Canon's drawing routines.


This writes messages with Canon's builtin Fonts (useful if you have trouble with ML fonts).

bfnt_puts("Hello, world!", x, y, foreground_color, background_color);

Dumping data from RAM[]

Code mix from AJ and Arm.Indy:

void dump_seg(start, size, filename)
    FILE *f;
    f = FIO_CreateFile(filename);
    if (f == INVALID_PTR)
       bmp_printf(FONT_SMALL, 120, 40, "FCreate: Err %s", filename);
    FIO_WriteFile(f, start, size);

Example (to be called while in Live View mode, e.g. from draw_zebra):

dump_seg(0x40D07800, 1440*480, "B:/vram1.dat");

This is how I've found the YUV 4:2:2 buffer (for zebra and histogram).

Debug console[]

This is present in recent 550D builds. Code is 99% identical to the script console from LUA-enabled builds.


  • console_show() / console_hide()
  • console_puts(const char* str)
  • console_printf(const char* fmt, ...)

DebugMsg's from ML are also displayed to the debug console. The contents of the console is saved to CONSOLE.LOG; it's updated as soon as a new message appears (which allows you to spy the shutdown sequence, for example).

Further reading[]


DryOS shell debug functions