Giter Site home page Giter Site logo

cyrus-and / gdb-dashboard Goto Github PK

View Code? Open in Web Editor NEW
10.3K 219.0 743.0 357 KB

Modular visual interface for GDB in Python

License: MIT License

Python 100.00%
subcommands gdb-command dashboard-styles gdb-commands divide stylable-attributes gdb python debugger visual

gdb-dashboard's Introduction

GDB dashboard

GDB dashboard is a standalone .gdbinit file written using the Python API that enables a modular interface showing relevant information about the program being debugged. Its main goal is to reduce the number of GDB commands needed to inspect the status of current program thus allowing the developer to primarily focus on the control flow.

Screenshot

Quickstart

Just place .gdbinit in your home directory, for example with:

wget -P ~ https://github.com/cyrus-and/gdb-dashboard/raw/master/.gdbinit

Optionally install Pygments to enable syntax highlighting:

pip install pygments

Then debug as usual, the dashboard will appear automatically every time the inferior program stops.

Keep in mind that no GDB command has been redefined, instead all the features are available via the main dashboard command (see help dashboard).

Head to the wiki to learn how to perform the most important tasks.

gdb-dashboard's People

Contributors

10110111 avatar alfunx avatar braiden avatar ccalmels avatar cyrus-and avatar jannewulf avatar javier-cabezas avatar karczex avatar lucianposton avatar milesfrain avatar n00byedge avatar nanoseb avatar povelikinrostislav avatar profdiesel avatar quinny avatar rcaputo avatar reinis avatar shuber2 avatar xeyownt avatar zofiazementa avatar zzhx2006 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gdb-dashboard's Issues

name mt is not defined

I am facing this error:
NameError: name 'mt' is not defined. Please help.

entire log:
Traceback (most recent call last):
File "", line 296, in
File "", line 303, in on_continue
File "", line 257, in divider
File "", line 234, in ansi
NameError: name 'mt' is not defined
Missing separate debuginfos, use: dnf debuginfo-install glibc-2.21-5.fc22.x86_64

Breakpoint 1, main () at delete_entire_list.c:48
48 struct node *head = NULL;
Traceback (most recent call last):
File "", line 297, in
File "", line 308, in on_stop
File "", line 339, in display
File "", line 801, in lines
File "", line 234, in ansi
NameError: name 'mt' is not defined

disconnect stop/cont events for db -enabled off

I would suggest disconnecting the stop and cont events when dashboard is disabled (and reconnect them when enabled). event connections can significantly slow things down if you have define some commands on a breakpoint like this:

commands 1
output somevar
cont
end

aka a trace point in msvc terminology. When doing this kind of debugging it's handy to have a way to "fully" disable dashboard.

AttributeError: 'module' object has no attribute 'COMMAND_USER'

here are my commond:
$ wget -P ~ git.io/.gdbinit
$ gdb

it should be a more gui interface, but i didn't see it.
the Traceback here:
Traceback (most recent call last):
File "", line 1, in
File "", line 241, in start
File "", line 171, in init
AttributeError: 'module' object has no attribute 'COMMAND_USER'

Feature request - mixed disassembly in source module

It'd be nice if the source module allowed for mixed disassembly to be displayed (equivalent of the disassemble /m flag).

The mixed dissassembly could be enabled via a style flag on the source module e.g.

List of dashboard source -style subcommands:

dashboard source -style disassembly -- Mixed disassembly visibility flag

(or it could be a style flag on the Assembly module)

If this were an option, i would probably just turn off the assembly module altogether, then use a quick alias/function to toggle the the mixed disassmbly in the source module.

how to expand stack?

It seems the stack info is folded when there is more than two levels. How can I expand it?

Error occured in Python command: 'dict' object has no attribute 'iteritems'

I am getting the following error:

 >>> db
 Traceback (most recent call last):
  File "<string>", line 545, in invoke
  File "<string>", line 293, in redisplay
  File "<string>", line 327, in render
AttributeError: 'dict' object has no attribute 'iteritems'
Error occurred in Python command: 'dict' object has no attribute 'iteritems'

I don't know what could cause this.

$ python --version && python2 --version
Python 3.5.2
Python 2.7.12
$ pacman -Qi gdb-dashboard | grep Version
Version         : 0.1.2-1

$ cat .gdbinit.d/main
set auto-load safe-path
set follow-fork-mode child
#dashboard -style syntax_highlighting "monokai"

It's worth noting that my process forks, in case that changes anything.

gdb.error: Alias already exists: db

I get this error from this line:
run('alias -a db = dashboard')

I'm seeing this both in my Ubuntu and Mac machine.

source /home/mozilla/scratch/gdb-dashboard/.gdbinit

Traceback (most recent call last):
File "", line 1, in
File "", line 289, in start
File "", line 116, in run
gdb.error: Alias already exists: db
/home/mozilla/scratch/gdb-dashboard/.gdbinit:1198: Error in sourced command file:

Python/GDB compatibility issues

Problem:
I tried to run gdb-dashboard on centos 6/7, but failed on both platforms.

Possible Reason:
It looks like centos 6's gdb uses python 2.6, which does not have subprocess.check_output supported, meanwhile centos 7 fails to work with the error as gdb module " 'module' object has no attribute 'COMPLETE_EXPRESSION' ".

Platform Information:
Centos 6's gdb links to python 2.7.6 and centos 6 links to python 2.6.6.

Not able to run on MacOS Mavericks

I've installed gdb through homebrew and gdb-dashboard as described with wget, but when I run gdb against a python script the gdb shell starts. What I'm missing?

Fails on UTF-8 output.

I was trying this out on some UTF-8 stuff I made to test things out and it doesn't seem to be able to handle the letter å.

node_create (line=0x100800600 L"Tre små") at node.c:9
Traceback (most recent call last):
  File "<string>", line 187, in <lambda>
  File "<string>", line 206, in on_stop
  File "<string>", line 243, in build
  File "<string>", line 803, in lines
  File "<string>", line 843, in fetch_frame_info
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe5' in position 20: ordinal not in range(128)
>>>

How to use the fullsize of the terminal if output the source part to another terminal?

For example, I open two panes side-by-side using tmux/screen, and I use dashboard source -output source.c /dev/pts/10 to the right pane which is /dev/pts/10 to view the source code part, but only 5 (which is default) lines of code is shown in /dev/pts/10, I can change the default value, but it is fixed anyway.

How can I make the source part use the rest (in this case, fullsize) of the terminal if I output it to another terminal?

Dashboard crashes with MIPS target

When using this with a MIPS remote target, I get this crash at connect time

Traceback (most recent call last):
  File "<string>", line 180, in <lambda>
  File "<string>", line 191, in on_stop
  File "<string>", line 222, in display
  File "<string>", line 952, in lines

I think the problem is for MIPS, info registers gives you the output

>>> info registers
          zero       at       v0       v1       a0       a1       a2       a3
 R0   00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
            t0       t1       t2       t3       t4       t5       t6       t7
 R8   00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
            s0       s1       s2       s3       s4       s5       s6       s7
 R16  00536b28 7e3697b4 00531d74 00000000 7e369a9d 7e3694eb 00000008 7e3694e6 
            t8       t9       k0       k1       gp       sp       s8       ra
 R24  00000000 00000000 00000000 00000000 00000000 78fabf60 7e3694f0 00000000 
        status       lo       hi badvaddr    cause       pc
      01000013 cf24a617 0013b819 004734a0 00802420 30eea250 
          fcsr      fir      hi1      lo1      hi2      lo2      hi3      lo3
      00000000 01739700 00000000 00000000 00000000 00000000 00000000 00000000 
        dspctl  restart
      00000000 00000000 

which is a special format that's just for MIPS, defined in gdb/mips-tdep.c.

Cannot write the dashboard: [Errno 10] No child process

Hello,

I'm using dashboard to debug a custom cpu with a custom gdb back-end.
When starting the debugger, I frequently get the message

Cannot write the dashboard: [Errno 10] No child process

To fix that I have to type da several times, until it works. When it works, it stay attached.

Any idea how I can debug that?
(this is on commit 379a81a)

another UnicodeEncodeError

Traceback (most recent call last):
File "", line 243, in on_stop
File "", line 294, in build
File "", line 733, in lines
UnicodeEncodeError: 'ascii' codec can't encode character u'\xb7' in position 122: ordinal not in range(128)

Provide pretty stack trace as a separate command

gdb-dashboard stack trace is so readable that it would be great to have it as an individual command. Meanwhile, I switch between

define dashboard-stack
  dashboard stack -style limit 0
  dashboard stack -style locals True
  dashboard -layout stack assembly expressions history memory registers source threads
end

and

define dashboard-default
  dashboard stack -style limit 3
  dashboard stack -style locals False
  dashboard -layout assembly expressions history memory registers source stack threads
end

Memory doesn't show.

For some reason, Memory tab is a simple line with nothing in it. Any way to solve this problem?

I got latest .gdbinit from this repo, i got GDB version 7.10.

Cannot write the dashboard: Invalid character '?' in expression

On my platform, info registers returns a very huge list of registers (like 80 registers), some registers being quite long.

Sometimes, when starting dashboard, I get the error:

Cannot write the dashboard: Invalid character '?' in expression

Where the ? is some strange symbol character. When that happens, dashboard fails to print the register list. In fact, when issuing the command info reg in the CLI, I noticed that the output is corrupted for some registers (usually the long ones, where some funny characters appears here and there).

This problem happens at random. Starting gdb several times, I maybe get the problem 1 out of 4. When I get it, info reg remains corrupted for the whole session it seems.

I don't know if this is a problem in dashboard, but it only happens when I use dashboard. I tried like 10+ times without dashboard, and can't reproduce the problem.

Any idea what could corrupt the output of gdb?

Note that this is very low priority because actually I currently patched dashboard to only keep the most important registers, and these apparently are never corrupted.

consider tagging a git release

Hey, it would be awesome if you can start tagging git releases sometimes, this would also aid the way package maintainers could start packaging this 😄
Would love to soon see a tag 👍

32 bit applications should have 32 bit pointers

Right now with dashboard, when debugging 32-bit applications (on 64-bit host), all offsets, pointers, etc, are displayed as 64-bit long. They should be shown as proper to their target.
Sample, is:
0x000000007022827f
should be:
0x7022827f

style_low Text isn't shown properly on putty

Not really an issue, but I'd recommend adding some FAQ section in readme to answer this. It drove me nuts and as putty is very popular I assume others are going to run into this issue. Putty shows bold grey text as black, which is the default background.

To fix:
either change the color: dashboard -style style_low '36'
Or change putty settings: window->Colours->'Indicate bolded text by changing by changing:'->The colour\Both

Dashboard crashes external debuggers

Tested on Ubuntu Mint 14.04.

With .gdbinit copied to home directory, dashboard works as it should from terminal windows, but it breaks external GDB frontends like Nemiver or Qt Creator, they pop-up an unexpected crash error window without any helpful debug info.

If .gdbinit is removed from home directory, they work fine again.

Center the output of Source around current gdb line

In dashboard source -style context X the code is not centered around the current line of gdb (info line). If X is big enough (relative to the size of the terminal), you can even miss the current gdb line without scrolling.

How to reload .gdbinit once modified it?

How to reload .gdbinit once modified it? For example, I add lines or modify the lines in .gdbinit, and I want to see the effect, but I don't want to exit-start gdb again, how can I do that inside the current gdb session?

I tried to execute source ~/.gdbinit at gdb prompt, the changes will take affect, but the command will output some error message such as:

Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "<string>", line 386, in start
  File "<string>", line 127, in run
gdb.error: Alias already exists: db
~/.gdbinit:1368: Error in sourced command file:
Error while executing Python code.

ValueError: invalid literal for int() with base 10

Traceback (most recent call last):
  File "<string>", line 180, in <lambda>
  File "<string>", line 191, in on_stop
  File "<string>", line 222, in display
  File "<string>", line 582, in lines
ValueError: invalid literal for int() with base 10: 'file: "/home/andy/dev/lmms/build/src/../../include/AudioDevice.h", line number: 126'

line in question:

        m_sampleRate = _new_sr;

Error on Debian

After obtaining the .gdbinit file and running gdb, Debian (Jessie) Mint has en error.

$ wget -P ~ git.io/.gdbinit
$ gdb

This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
http://www.gnu.org/software/gdb/bugs/.
Traceback (most recent call last):
File "", line 1, in
File "", line 246, in start
File "", line 199, in load_modules
File "", line 335, in init
File "", line 362, in add_subcommands
File "", line 1065, in commands
AttributeError: 'module' object has no attribute 'COMPLETE_EXPRESSION'
/home/mlncn/.gdbinit:1093: Error in sourced command file:
Error while executing Python code.

Strange highlighting

I just noticed this strange highlighting behaviour while providing this sample code on reddit:

#include <memory>
#include <future>

int main() {
    using namespace std;

    auto foo = make_unique<int>(42);

    auto inc1 = async(launch::async, [foo = move(foo)] { (*foo)++; });

    // ...

    auto inc2 = async(launch::async, [foo = move(foo)] { (*foo)++; });
}

I was checking how gdb would behave on segfault. The c++ sample was compiled with g++ -g3 -O0 -std=c++14 -Wall -Wextra -pedantic -lpthread sample.cpp -o sample.

Running gdb ./sample + >>> r gives:

screenshot from 2017-01-30 18-55-31
Notice how mov DWORD PTR [rax],edx is not correctly highlighted.

My custom gdb-dashboard initialization is:

set disassembly-flavor intel
dashboard -style syntax_highlighting "algol_nu"

define hookpost-up
dashboard
end

define hookpost-down
dashboard
end

How to create an alias/function for a command like bash/fish?

Every time I open gdb to debug a binary, I create a pane side by side (I use tmux), and then use tty command to get the info of the new created pane, and then back to the gdb session pane, use

dashboard -output /dev/pts/N

to ouput the info to the new created pane.

So, if there a way to create an alias/function, for example, if I'm in fish-shell, I would this:

function dod
    dashboard -output /dev/pts/$argv[1]
end

so in gdb session I can just use dod N to execute the long 'dashboard -output /dev/pts/N' command.

Or you have better solution?

BTW: I have no knowledge of Python.

Add a datastructure browser

This is a great extension to gdb, thanks!

Have you ever worked with ddd, the Data Display Debugger? It has a very handy feature where data structures are displayed a connected boxes, and I can browse them. Together with gdb's STL pretty printer this would be a very helpful additional dashboard panel, ncurses style.

Any chance you'd add something like that?

Invisible GDB prompt

Reproduction:
mozilla@mozgfx-rr-orange-hunter-1:~/scratch/gdb-dashboard$ gdb sleep
GNU gdb (Ubuntu 7.10-1ubuntu2) 7.10
<...>
(gdb) source /home/mozilla/scratch/gdb-dashboard/.gdbinit

This gives no prompt on my Mac and Linux box.

Displaying multi-byte values in the Memory view

It would be useful to add support to display memory words (16/32/64 bits) in the Memory view akin to the gdb x command. The gdb x command is often used with more than 1 byte arguments and similar functionality would be nice to have in the dashboard.

I'm already working on this but I wanted to document this feature request if someone else has this on mind too. In either case, I'll try to send a pull request soon. :-)

Exception in Assembly Module

When debugging a C++ program in gdb, I get this error as soon as I hit a breakpoint:

Traceback (most recent call last):
  File "<string>", line 184, in <lambda>
  File "<string>", line 203, in on_stop
  File "<string>", line 240, in build
  File "<string>", line 683, in lines
ValueError: invalid literal for int() with base 16: '0x000000010002e710:\tpush'

It looks like there's some issue with parsing some gdb output in the assembly module, because disabling it with

dashboard assembly

removes the error upon hitting a breakpoint.

Fixes for MS Windows

Hi,

Here is small patch to make dashboard working in MS Windows.
Issues fixed:

  1. excluded imports not available in Windows
  2. style map updated to exclude UTF-8 chars - Windows console dont support them.
  3. implemented Windows-specific terminal width calculation. Algorithm is like this:
    3.1 try to use ANSICON env variable - it contains necessary values
    3.2 pipe "mode con:" command - it outputs term width/height
    3.3 try use LINES and COLUMNS env vars if available
    3.4 fall back to 80x25

Windows console does not support ANSI control sequences directly, but there is ANSICON utility which fixes this. You can get it here: https://github.com/adoxa/ansicon

patch.zip

Simple editor integrations (tips and tricks)

This is not so much a feature request or bug report about gdb-dashboard, but more like a tip/trick that might spark some discussion. I think this sort of thing falls outside the scope of gdb-dashboard but it might be interesting to hear how other developers deal with this --

Often I'm in gdb-dashboard on a breakpoint, and maybe I've moved up the callstack a few times and I realize I'd like to have a better look at the current frame's source/line within a text editor (can navigate around the file more easily, search for things, make modifications, etc). To quickly accomplish this, I use something like this in my .gdbinit:

define vo
python
import os
sal = gdb.selected_frame().find_sal()
current_line = sal.line
if current_line != 0:
    theCmd = "e " + sal.symtab.fullname() + " | +call cursor(" + str(current_line) + ", 0)"
    #theCmd = "vim --remote-silent +\"" + str(current_line) + "G|\" \"" + sal.symtab.fullname() + "\""
    os.system("tmux set-buffer \"" + theCmd + "\"")
    print(theCmd)
end
end

With this script I can type "vo" in gdb and it will put the appropriate vim/ex command onto my tmux buffer so i can paste that into my current vim pane and go right to the location I was just dealing with in gdb. If preferred, you could also run vim --remote-silent with a command and have "vo" immediately open it in your current vim session. I presume emacs and other editors have similar functionality, so you can adapt it to your needs.

Does anyone else use something like this? Any other tips and tricks others are using to integrate gdb with tmux/vim/emacs/etc?

Interferes with QtCreator

Hi there,
first of all, thank for such an awesome tool, I use it everyday and it saves my life :)

Problem report:
Qt Creator 4.1.0 (Qt 5.7) 64b cannot debug any external app with gdb-dashboard's .gdbinit. It crashes with an error
*** UNEXPECTED STATE TRANSITION: Debugger::Internal::GdbPlainEngine(0x449b1a0, name = "GdbEngine") "State changed from EngineSetupRequested(1) to EngineShutdownRequested(20).
Qt's UI said The gdb process terminated. After removal of .gdbinit everything worked as expected.
The same was reproduced with Qt Creator 3.0.1 (Qt 5.2.1).

"dashboard" in a hookpost-next with recent gdb versions fails

Firstly, I'm using the latest version of gdb, 7.11, but anything newer than bminor/binutils-gdb@329ea57 is fine to reproduce the issue.

If I define the following in my .gdbinit:

define hookpost-next
dashboard
end

Any time I use 'next', I get the following:

Traceback (most recent call last):
  File "<string>", line 467, in invoke
  File "<string>", line 260, in redisplay
  File "<string>", line 283, in build
  File "<string>", line 744, in lines
gdb.error: No frame is currently selected.
Error occurred in Python command: No frame is currently selected.

It would appear that gdb is trying to run certain things async, and it calls the hookpost-next before the current frame is even set. Interestingly, hookpost-up or hookpost-down with "dashboard" does not cause a problem.

I grabbed the latest git checkout of gdb and ran a bisect on it, and narrowed it down to this commit when the problem started happening:
bminor/binutils-gdb@329ea57
Which is actually quite old.

No combination of "mt set target-async off" or "set target-async off" seemed to help the issue.
Also potentially relevant:
https://sourceware.org/ml/gdb-prs/2014-q4/msg00102.html

My current workaround is:

define n
next
dashboard
vo
end

Then I use 'n' instead of 'next'. This actually works fine.
So I guess this is more of a "gotchas with using hookpost-next and workaround" thread rather than a bug report :)

Unless you have an idea on how to make hookpost-next work properly -- I'm actually curious if you observe the same issue.

gdb-dashboard loses "Output/messages" on update

I've noticed that the content of the Output/messages area gets reset any time dashboard is executed. Is this expected? Is there any way to preserve the content of the Output/messages area across dashboard updates?

error on initialization

after issuing start

>>> start

get this output

Traceback (most recent call last):
  File "", line 199, in 
  File "", line 215, in on_stop
  File "", line 254, in build
  File "", line 961, in lines
  File "", line 119, in run
gdb.error: Undefined command: "when".  Try "help".

and it keeps showing after every command (next, step)

calling

>>> dashboard -layout source

fixes error and subsequent commands do not output that trace.

Cgdb-like source listing. [feature request]

I use cgdb instead of gdb because of the nice source code listing. Whenever I use 'up/down/next/step...', I know where I'm at, all the time. Other than that, I have many issues with cgdb and I would like to stop using it. The only thing I want in gdb is the nice code listing, which gdb-dashboard provides, but only half way through.

I see gdb-dashboard is using 'gdb.newest_frame()' in some places and it's only showing the source code of the last frame and not the current frame. Can you make gdb-dashboard behave like cgdb in terms of source code listing when using 'up/down' commands to change the current frame. Have a look at cgdb behavior and tell me what you think.

Reduce blanking effect?

Do you think it would be possible to reduce the amount of time that the terminal becomes blank between the updates?

i.e. Does it currently happen like this?
OnUpdate:
Clear Terminal
Gather / Print results

And if so, could it work more like this?
OnUpdate:
Gather / Buffer results
Clear terminal
Print buffered results

My reasoning:
The blanking causes me to lose my place visually. For example, if I'm trying to keep my eye on a particular watch expression, and I "next" (which triggers an update), The terminal blanks for probably a good 500-800 milliseconds before being redrawn, which causes me to lose my place...

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.